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() {