diff options
author | Hop311 <hop3114@gmail.com> | 2023-04-07 01:42:53 +0200 |
---|---|---|
committer | Hop311 <hop3114@gmail.com> | 2023-04-07 01:42:53 +0200 |
commit | 513a1328edb89ac695c70164158933aee4546cd7 (patch) | |
tree | 8d979d4e8c728bb80543aa13e037a328829122fd /extension/src/MapSingleton.cpp | |
parent | 14c2358c7837e644349ea37866607fcd1459d2bc (diff) |
Province index and colour lookup texture
Diffstat (limited to 'extension/src/MapSingleton.cpp')
-rw-r--r-- | extension/src/MapSingleton.cpp | 125 |
1 files changed, 111 insertions, 14 deletions
diff --git a/extension/src/MapSingleton.cpp b/extension/src/MapSingleton.cpp index 9d13496..71977da 100644 --- a/extension/src/MapSingleton.cpp +++ b/extension/src/MapSingleton.cpp @@ -12,8 +12,11 @@ MapSingleton* MapSingleton::singleton = nullptr; void MapSingleton::_bind_methods() { ClassDB::bind_method(D_METHOD("load_province_identifier_file", "file_path"), &MapSingleton::load_province_identifier_file); ClassDB::bind_method(D_METHOD("load_province_shape_file", "file_path"), &MapSingleton::load_province_shape_file); - ClassDB::bind_method(D_METHOD("get_province_shape_image"), &MapSingleton::get_province_shape_image); - ClassDB::bind_method(D_METHOD("get_province_identifier_from_colour", "colour"), &MapSingleton::get_province_identifier_from_colour); + ClassDB::bind_method(D_METHOD("get_province_identifier_from_pixel_coords", "coords"), &MapSingleton::get_province_identifier_from_pixel_coords); + ClassDB::bind_method(D_METHOD("get_width"), &MapSingleton::get_width); + ClassDB::bind_method(D_METHOD("get_height"), &MapSingleton::get_height); + ClassDB::bind_method(D_METHOD("get_province_index_image"), &MapSingleton::get_province_index_image); + ClassDB::bind_method(D_METHOD("get_province_colour_image"), &MapSingleton::get_province_colour_image); } MapSingleton* MapSingleton::get_singleton() { @@ -105,20 +108,17 @@ Error MapSingleton::load_province_identifier_file(String const& file_path) { continue; } std::string error_message; - if (map.add_province(identifier.utf8().get_data(), colour, error_message)) { - UtilityFunctions::print(error_message.c_str()); - } else { + if (!map.add_province(identifier.utf8().get_data(), colour, error_message)) { UtilityFunctions::push_error(error_message.c_str()); err = FAILED; } } + map.lock_provinces(); return err; } -String MapSingleton::get_province_identifier_from_colour(Province::colour_t colour) { - const Province* province = map.get_province_by_colour(colour); - if (province) return province->get_identifier().c_str(); - else return String{}; +static Province::colour_t colour_at(PackedByteArray const& colour_data_array, int32_t idx) { + return (colour_data_array[idx * 3] << 16) | (colour_data_array[idx * 3 + 1] << 8) | colour_data_array[idx * 3 + 2]; } Error MapSingleton::load_province_shape_file(String const& file_path) { @@ -133,13 +133,13 @@ Error MapSingleton::load_province_shape_file(String const& file_path) { province_shape_image.unref(); return err; } - int32_t width = province_shape_image->get_width(); - int32_t height = province_shape_image->get_height(); + width = province_shape_image->get_width(); + height = province_shape_image->get_height(); if (width < 1 || height < 1) { UtilityFunctions::push_error("Invalid dimensions (", width, "x", height, ") for province shape file: ", file_path); err = FAILED; } - static const Image::Format expected_format = Image::Format::FORMAT_RGB8; + static const Image::Format expected_format = Image::FORMAT_RGB8; Image::Format format = province_shape_image->get_format(); if (format != expected_format) { UtilityFunctions::push_error("Invalid format (", format, ", should be ", expected_format, ") for province shape file: ", file_path); @@ -149,9 +149,106 @@ Error MapSingleton::load_province_shape_file(String const& file_path) { province_shape_image.unref(); return err; } + + std::vector<bool> province_checklist(map.get_province_count()); + + PackedByteArray shape_data_array = province_shape_image->get_data(), index_data_array; + index_data_array.resize(width * height * sizeof(Province::index_t)); + Province::index_t* index_data = reinterpret_cast<Province::index_t*>(index_data_array.ptrw()); + + for (int32_t y = 0; y < height; ++y) { + for (int32_t x = 0; x < width; ++x) { + const int32_t idx = x + y * width; + const Province::colour_t colour = colour_at(shape_data_array, idx); + if (colour == Province::NULL_COLOUR) { + index_data[idx] = Province::NULL_INDEX; + continue; + } + if (x > 0) { + const int32_t jdx = idx - 1; + if (colour_at(shape_data_array, jdx) == colour) { + index_data[idx] = index_data[jdx]; + continue; + } + } + if (y > 0) { + const int32_t jdx = idx - width; + if (colour_at(shape_data_array, jdx) == colour) { + index_data[idx] = index_data[jdx]; + continue; + } + } + const Province* province = map.get_province_by_colour(colour); + if (province) { + Province::index_t index = province->get_index(); + index_data[idx] = index; + province_checklist[index - 1] = true; + continue; + } + UtilityFunctions::push_error("Unrecognised province colour ", Province::colour_to_hex_string(colour).c_str(), " at (", x, ", ", y, ")"); + err = FAILED; + index_data[idx] = Province::NULL_INDEX; + } + } + + for (size_t idx = 0; idx < province_checklist.size(); ++idx) { + if (!province_checklist[idx]) { + Province* province = map.get_province_by_index(idx + 1); + if (province) UtilityFunctions::push_error("Province missing from shape image: ", province->to_string().c_str()); + else UtilityFunctions::push_error("Province missing for index: ", idx + 1); + err = FAILED; + } + } + + province_index_image = Image::create_from_data(width, height, false, Image::FORMAT_RG8, index_data_array); + if (province_index_image.is_null()) { + UtilityFunctions::push_error("Failed to create province ID image"); + err = FAILED; + } + + PackedByteArray colour_data_array; + colour_data_array.resize((Province::MAX_INDEX + 1) * 3); + for (int64_t idx = 1; idx <= map.get_province_count(); ++idx) { + const Province* province = map.get_province_by_index(idx); + if (province) { + const Province::colour_t colour = province->get_colour(); + colour_data_array[3 * idx + 0] = (colour >> 16) & 0xFF; + colour_data_array[3 * idx + 1] = (colour >> 8) & 0xFF; + colour_data_array[3 * idx + 2] = colour & 0xFF; + } else UtilityFunctions::push_error("Missing province at index ", idx); + } + static const int32_t PROVINCE_INDEX_SQRT = 1 << (sizeof(Province::index_t) * 4); + province_colour_image = Image::create_from_data(PROVINCE_INDEX_SQRT, PROVINCE_INDEX_SQRT, false, Image::FORMAT_RGB8, colour_data_array); + if (province_colour_image.is_null()) { + UtilityFunctions::push_error("Failed to create province colour image"); + err = FAILED; + } + return err; } -Ref<Image> MapSingleton::get_province_shape_image() const { - return province_shape_image; +String MapSingleton::get_province_identifier_from_pixel_coords(Vector2i const& coords) { + if (province_index_image.is_valid() && 0 <= coords.x && coords.x < width && 0 <= coords.y && coords.y < height) { + const PackedByteArray index_data_array = province_index_image->get_data(); + const Province::index_t* index_data = reinterpret_cast<const Province::index_t*>(index_data_array.ptr()); + const Province* province = map.get_province_by_colour(index_data[coords.x + coords.y * width]); + if (province) return province->get_identifier().c_str(); + } + return String{}; +} + +int32_t MapSingleton::get_width() const { + return width; +} + +int32_t MapSingleton::get_height() const { + return height; +} + +Ref<Image> MapSingleton::get_province_index_image() const { + return province_index_image; +} + +Ref<Image> MapSingleton::get_province_colour_image() const { + return province_colour_image; } |