diff --git a/modules/wfc/SCsub b/modules/wfc/SCsub index 14fb43549..aa03137ae 100644 --- a/modules/wfc/SCsub +++ b/modules/wfc/SCsub @@ -10,3 +10,5 @@ env_wfc.add_source_files(env.modules_sources, "wave_form_collapse.cpp") env_wfc.add_source_files(env.modules_sources, "tiling_wave_form_collapse.cpp") env_wfc.add_source_files(env.modules_sources, "overlapping_wave_form_collapse.cpp") + +env_wfc.add_source_files(env.modules_sources, "image_indexer.cpp") diff --git a/modules/wfc/config.py b/modules/wfc/config.py index b98e90691..8690785f8 100644 --- a/modules/wfc/config.py +++ b/modules/wfc/config.py @@ -11,6 +11,7 @@ def get_doc_classes(): "WaveFormCollapse", "TilingWaveFormCollapse", "OverlappingWaveFormCollapse", + "ImageIndexer", ] diff --git a/modules/wfc/doc_classes/ImageIndexer.xml b/modules/wfc/doc_classes/ImageIndexer.xml new file mode 100644 index 000000000..94e1bc8d2 --- /dev/null +++ b/modules/wfc/doc_classes/ImageIndexer.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/wfc/image_indexer.cpp b/modules/wfc/image_indexer.cpp new file mode 100644 index 000000000..e37d58fe5 --- /dev/null +++ b/modules/wfc/image_indexer.cpp @@ -0,0 +1,76 @@ + +#include "image_indexer.h" + +#include "core/oa_hash_map.h" + +PoolColorArray ImageIndexer::get_colors() { + return _colors; +} +PoolIntArray ImageIndexer::get_color_indices() { + return _color_indices; +} + +void ImageIndexer::index_image(Ref image) { + ERR_FAIL_COND(!image.is_valid()); + + _colors.resize(0); + _color_indices.resize(0); + + OAHashMap col_map; + + image->lock(); + + int w = image->get_width(); + int h = image->get_height(); + + for (int x = 0; x < w; ++x) { + for (int y = 0; y < h; ++y) { + Color c = image->get_pixel(x, y); + + int color_index = 0; + if (!col_map.lookup(c, color_index)) { + color_index = _colors.size(); + _colors.push_back(c); + col_map.set(c, color_index); + } + + _color_indices.push_back(color_index); + } + } + + image->unlock(); +} + +PoolByteArray ImageIndexer::indices_to_argb8_data(const PoolIntArray &indices) { + PoolByteArray arr; + arr.resize(indices.size() * 4); + + PoolByteArray::Write arrw = arr.write(); + PoolIntArray::Read indr = indices.read(); + int s = indices.size(); + + for (int i = 0; i < s; ++i) { + int arrind = i * 4; + + Color c = _colors[indr[i]]; + + arrw[arrind] = static_cast(c.r * 255); + arrw[arrind + 1] = static_cast(c.g * 255); + arrw[arrind + 2] = static_cast(c.b * 255); + arrw[arrind + 3] = static_cast(c.a * 255); + } + + return arr; +} + +ImageIndexer::ImageIndexer() { +} +ImageIndexer::~ImageIndexer() { +} + +void ImageIndexer::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_colors"), &ImageIndexer::get_colors); + ClassDB::bind_method(D_METHOD("get_color_indices"), &ImageIndexer::get_color_indices); + ClassDB::bind_method(D_METHOD("index_image"), &ImageIndexer::index_image); + ClassDB::bind_method(D_METHOD("indices_to_argb8_data"), &ImageIndexer::indices_to_argb8_data); +} diff --git a/modules/wfc/image_indexer.h b/modules/wfc/image_indexer.h new file mode 100644 index 000000000..5e4476198 --- /dev/null +++ b/modules/wfc/image_indexer.h @@ -0,0 +1,30 @@ +#ifndef IMAGE_INDEXER_H +#define IMAGE_INDEXER_H + +#include "core/image.h" +#include "core/reference.h" +#include "core/variant.h" + +class ImageIndexer : public Reference { + GDCLASS(ImageIndexer, Reference); + +public: + PoolColorArray get_colors(); + PoolIntArray get_color_indices(); + + void index_image(Ref image); + + PoolByteArray indices_to_argb8_data(const PoolIntArray &indices); + + ImageIndexer(); + ~ImageIndexer(); + +protected: + static void _bind_methods(); + +private: + PoolColorArray _colors; + PoolIntArray _color_indices; +}; + +#endif diff --git a/modules/wfc/register_types.cpp b/modules/wfc/register_types.cpp index 2a56378d8..9867e239f 100644 --- a/modules/wfc/register_types.cpp +++ b/modules/wfc/register_types.cpp @@ -4,11 +4,13 @@ #include "overlapping_wave_form_collapse.h" #include "tiling_wave_form_collapse.h" #include "wave_form_collapse.h" +#include "image_indexer.h" void register_wfc_types() { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); } void unregister_wfc_types() {