From 6736ff17fd303ce52743165f70e78e5b95fec5ed Mon Sep 17 00:00:00 2001 From: Relintai Date: Sun, 24 Apr 2022 01:49:26 +0200 Subject: [PATCH] Bindings for TilingWaveFormCollapse. --- modules/wfc/tiling_wave_form_collapse.cpp | 233 ++++++++++++++++++++++ modules/wfc/tiling_wave_form_collapse.h | 53 ++++- 2 files changed, 282 insertions(+), 4 deletions(-) diff --git a/modules/wfc/tiling_wave_form_collapse.cpp b/modules/wfc/tiling_wave_form_collapse.cpp index 2a6bd710d..5c5ca0ebc 100644 --- a/modules/wfc/tiling_wave_form_collapse.cpp +++ b/modules/wfc/tiling_wave_form_collapse.cpp @@ -91,6 +91,55 @@ Vector> Tile::generate_oriented(Array2D data, WaveFormCollapse return oriented; } +void Tile::set_generate_data(const PoolIntArray &p_data, const int width, const int height) { + data.clear(); + Array2D d(p_data, height, width); + data = generate_oriented(d, symmetry); +} + +PoolIntArray Tile::data_get(const int index) { + ERR_FAIL_INDEX_V(index, data.size(), PoolIntArray()); + + const Array2D arr = data.write[index]; + PoolIntArray ret; + + const int *p = arr.data.ptr(); + int s = arr.data.size(); + + ret.resize(s); + PoolIntArray::Write w = ret.write(); + + for (int i = 0; i < s; ++i) { + w[i] = p[i]; + } + + w.release(); + + return ret; +} + +void Tile::data_set(const int index, const PoolIntArray &p_data, const int width, const int height) { + ERR_FAIL_INDEX(index, data.size()); + + data.write[index].set_data(p_data, height, width); +} + +void Tile::data_remove(const int index) { + ERR_FAIL_INDEX(index, data.size()); + + data.remove(index); +} + +Tile::Tile() { + symmetry = WaveFormCollapse::SYMMETRY_X; + weight = 0; +} + +Tile::Tile(WaveFormCollapse::Symmetry p_symmetry, double p_weight) { + symmetry = p_symmetry; + weight = p_weight; +} + // Create a tile with its differents orientations, its symmetries and its weight on the distribution of tiles. Tile::Tile(const Vector> &p_data, WaveFormCollapse::Symmetry p_symmetry, double p_weight) { data = p_data; @@ -106,6 +155,160 @@ Tile::Tile(const Array2D &p_data, WaveFormCollapse::Symmetry p_symmetry, do weight = p_weight; } +Tile::Tile(const PoolIntArray &p_data, const int width, const int height, WaveFormCollapse::Symmetry p_symmetry, double p_weight) { + Array2D d(p_data, height, width); + + data = generate_oriented(d, p_symmetry); + symmetry = p_symmetry; + weight = p_weight; +} + +int TilingWaveFormCollapse::tile_add_generated(const PoolIntArray &data, const int width, const int height, const WaveFormCollapse::Symmetry symmetry, const float weight) { + tiles.push_back(Tile(data, width, height, symmetry, weight)); + + return tiles.size() - 1; +} +int TilingWaveFormCollapse::tile_add(const WaveFormCollapse::Symmetry symmetry, const float weight) { + tiles.push_back(Tile(symmetry, weight)); + + return tiles.size() - 1; +} +int TilingWaveFormCollapse::tile_create() { + tiles.push_back(Tile()); + + return tiles.size() - 1; +} +void TilingWaveFormCollapse::tile_remove(const int tile_index) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.remove(tile_index); +} +int TilingWaveFormCollapse::tile_count_get() { + return tiles.size(); +} + +void TilingWaveFormCollapse::tile_data_add(const int tile_index, const PoolIntArray &data, const int width, const int height) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + Array2D d(data, height, width); + + tiles.write[tile_index].data.push_back(d); +} +void TilingWaveFormCollapse::tile_data_generated_add(const int tile_index, const PoolIntArray &data, const int width, const int height) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].set_generate_data(data, width, height); +} +PoolIntArray TilingWaveFormCollapse::tile_data_get(const int tile_index, const int data_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), PoolIntArray()); + + return tiles.write[tile_index].data_get(data_index); +} +void TilingWaveFormCollapse::tile_data_set(const int tile_index, const int data_index, const PoolIntArray &data, const int width, const int height) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].data_set(data_index, data, width, height); +} +void TilingWaveFormCollapse::tile_data_remove(const int tile_index, const int data_index) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].data_remove(data_index); +} +void TilingWaveFormCollapse::tile_data_clear(const int tile_index) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].data.clear(); +} +int TilingWaveFormCollapse::tile_data_count_get(const int tile_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0); + + return tiles[tile_index].data.size(); +} + +int TilingWaveFormCollapse::tile_width_get(const int tile_index, const int data_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0); + ERR_FAIL_INDEX_V(data_index, tiles[tile_index].data.size(), 0); + + return tiles[tile_index].data[data_index].width; +} +int TilingWaveFormCollapse::tile_height_get(const int tile_index, const int data_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0); + ERR_FAIL_INDEX_V(data_index, tiles[tile_index].data.size(), 0); + + return tiles[tile_index].data[data_index].height; +} + +WaveFormCollapse::Symmetry TilingWaveFormCollapse::tile_symmetry_get(const int tile_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), WaveFormCollapse::SYMMETRY_X); + + return tiles[tile_index].symmetry; +} +void TilingWaveFormCollapse::tile_symmetry_set(const int tile_index, const WaveFormCollapse::Symmetry val) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].symmetry = val; +} + +float TilingWaveFormCollapse::tile_weight_get(const int tile_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0); + + return tiles[tile_index].weight; +} +void TilingWaveFormCollapse::tile_weight_set(const int tile_index, const float val) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].weight = val; +} + +String TilingWaveFormCollapse::tile_name_get(const int tile_index) { + ERR_FAIL_INDEX_V(tile_index, tiles.size(), String()); + + return tiles[tile_index].name; +} +void TilingWaveFormCollapse::tile_name_set(const int tile_index, const String &val) { + ERR_FAIL_INDEX(tile_index, tiles.size()); + + tiles.write[tile_index].name = val; +} + +int TilingWaveFormCollapse::neighbour_data_add(const int n1, const int n2, const int n3, const int n4) { + NeighbourData d(n1, n2, n3, n4); + + neighbors.push_back(d); + + return neighbors.size() - 1; +} +PoolIntArray TilingWaveFormCollapse::neighbour_data_get(const int index) { + ERR_FAIL_INDEX_V(index, neighbors.size(), PoolIntArray()); + + const NeighbourData &d = neighbors[index]; + + PoolIntArray p; + p.resize(4); + + PoolIntArray::Write w = p.write(); + + for (int i = 0; i < 4; ++i) { + w[i] = d.data[i]; + } + + w.release(); + + return p; +} +void TilingWaveFormCollapse::neighbour_data_remove(const int index) { + ERR_FAIL_INDEX(index, neighbors.size()); + + neighbors.remove(index); +} +void TilingWaveFormCollapse::neighbour_data_set(const int index, const int n1, const int n2, const int n3, const int n4) { + ERR_FAIL_INDEX(index, neighbors.size()); + + NeighbourData d(n1, n2, n3, n4); + + neighbors.write[index] = d; +} + // Returns false if the given tile and orientation does not exist, or if the coordinates are not in the wave bool TilingWaveFormCollapse::set_tile(int tile_id, int orientation, int i, int j) { if (tile_id >= static_cast(oriented_tile_ids.size()) || orientation >= static_cast(oriented_tile_ids[tile_id].size()) || @@ -254,6 +457,36 @@ TilingWaveFormCollapse::~TilingWaveFormCollapse() { } void TilingWaveFormCollapse::_bind_methods() { + ClassDB::bind_method(D_METHOD("tile_add_generated", "data", "width", "height", "symmetry", "weight"), &TilingWaveFormCollapse::tile_add_generated); + ClassDB::bind_method(D_METHOD("tile_add", "symmetry", "weight"), &TilingWaveFormCollapse::tile_add); + ClassDB::bind_method(D_METHOD("tile_create"), &TilingWaveFormCollapse::tile_create); + ClassDB::bind_method(D_METHOD("tile_remove", "tile_index"), &TilingWaveFormCollapse::tile_remove); + ClassDB::bind_method(D_METHOD("tile_count_get"), &TilingWaveFormCollapse::tile_count_get); + + ClassDB::bind_method(D_METHOD("tile_data_add", "tile_index", "data", "width", "height"), &TilingWaveFormCollapse::tile_data_add); + ClassDB::bind_method(D_METHOD("tile_data_generated_add", "tile_index", "data", "width", "height"), &TilingWaveFormCollapse::tile_data_generated_add); + ClassDB::bind_method(D_METHOD("tile_data_get", "tile_index", "data_index"), &TilingWaveFormCollapse::tile_data_get); + ClassDB::bind_method(D_METHOD("tile_data_set", "tile_index", "data_index", "data", "width", "height"), &TilingWaveFormCollapse::tile_data_set); + ClassDB::bind_method(D_METHOD("tile_data_remove", "tile_index", "data_index"), &TilingWaveFormCollapse::tile_data_remove); + ClassDB::bind_method(D_METHOD("tile_data_clear", "tile_index"), &TilingWaveFormCollapse::tile_data_clear); + ClassDB::bind_method(D_METHOD("tile_data_count_get", "tile_index"), &TilingWaveFormCollapse::tile_data_count_get); + + ClassDB::bind_method(D_METHOD("tile_width_get", "tile_index", "data_index"), &TilingWaveFormCollapse::tile_width_get); + ClassDB::bind_method(D_METHOD("tile_height_get", "tile_index", "data_index"), &TilingWaveFormCollapse::tile_height_get); + + ClassDB::bind_method(D_METHOD("tile_symmetry_get", "tile_index"), &TilingWaveFormCollapse::tile_symmetry_get); + ClassDB::bind_method(D_METHOD("tile_symmetry_set", "tile_index", "val"), &TilingWaveFormCollapse::tile_symmetry_set); + + ClassDB::bind_method(D_METHOD("tile_weight_get", "tile_index"), &TilingWaveFormCollapse::tile_weight_get); + ClassDB::bind_method(D_METHOD("tile_weight_set", "tile_index", "val"), &TilingWaveFormCollapse::tile_weight_set); + + ClassDB::bind_method(D_METHOD("tile_name_get", "tile_index"), &TilingWaveFormCollapse::tile_name_get); + ClassDB::bind_method(D_METHOD("tile_name_set", "tile_index", "val"), &TilingWaveFormCollapse::tile_name_set); + + ClassDB::bind_method(D_METHOD("neighbour_data_add", "n1", "n2", "n3", "n4"), &TilingWaveFormCollapse::neighbour_data_add); + ClassDB::bind_method(D_METHOD("neighbour_data_get", "index"), &TilingWaveFormCollapse::neighbour_data_get); + ClassDB::bind_method(D_METHOD("neighbour_data_remove", "index"), &TilingWaveFormCollapse::neighbour_data_remove); + ClassDB::bind_method(D_METHOD("neighbour_data_set", "tile_index", "n1", "n2", "n3", "n4"), &TilingWaveFormCollapse::neighbour_data_set); } void TilingWaveFormCollapse::generate_propagator_add_helper(Tile::ActionMap *action_map1, Tile::ActionMap *action_map2, diff --git a/modules/wfc/tiling_wave_form_collapse.h b/modules/wfc/tiling_wave_form_collapse.h index 3ed04bc16..0d2628028 100644 --- a/modules/wfc/tiling_wave_form_collapse.h +++ b/modules/wfc/tiling_wave_form_collapse.h @@ -7,7 +7,6 @@ #include "wave_form_collapse.h" struct Tile { - struct ActionMap { Vector map[8]; @@ -21,16 +20,25 @@ struct Tile { static const uint8_t rotation_map[6][9]; static const uint8_t reflection_map[6][9]; + String name; Vector> data; WaveFormCollapse::Symmetry symmetry; double weight; static ActionMap generate_action_map(const WaveFormCollapse::Symmetry &symmetry); - static Vector> generate_oriented(Array2D data, WaveFormCollapse::Symmetry symmetry); + void set_generate_data(const PoolIntArray &p_data, const int width, const int height); + + PoolIntArray data_get(const int index); + void data_set(const int index, const PoolIntArray &p_data, const int width, const int height); + void data_remove(const int index); + + Tile(); + Tile(WaveFormCollapse::Symmetry p_symmetry, double p_weight); Tile(const Vector> &p_data, WaveFormCollapse::Symmetry p_symmetry, double p_weight); Tile(const Array2D &p_data, WaveFormCollapse::Symmetry p_symmetry, double p_weight); + Tile(const PoolIntArray &p_data, const int width, const int height, WaveFormCollapse::Symmetry p_symmetry, double p_weight); }; class TilingWaveFormCollapse : public WaveFormCollapse { @@ -45,6 +53,13 @@ public: data[i] = 0; } } + + NeighbourData(const int n1, const int n2, const int n3, const int n4) { + data[0] = n1; + data[1] = n2; + data[2] = n3; + data[3] = n4; + } }; struct DensePropagatorHelper { @@ -74,11 +89,41 @@ public: }; public: + int tile_add_generated(const PoolIntArray &data, const int width, const int height, const WaveFormCollapse::Symmetry symmetry, const float weight); + int tile_add(const WaveFormCollapse::Symmetry symmetry, const float weight); + int tile_create(); + void tile_remove(const int tile_index); + int tile_count_get(); + + void tile_data_add(const int tile_index, const PoolIntArray &data, const int width, const int height); + void tile_data_generated_add(const int tile_index, const PoolIntArray &data, const int width, const int height); + PoolIntArray tile_data_get(const int tile_index, const int data_index); + void tile_data_set(const int tile_index, const int data_index, const PoolIntArray &data, const int width, const int height); + void tile_data_remove(const int tile_index, const int data_index); + void tile_data_clear(const int tile_index); + int tile_data_count_get(const int tile_index); + + int tile_width_get(const int tile_index, const int data_index); + int tile_height_get(const int tile_index, const int data_index); + + WaveFormCollapse::Symmetry tile_symmetry_get(const int tile_index); + void tile_symmetry_set(const int tile_index, const WaveFormCollapse::Symmetry val); + + float tile_weight_get(const int tile_index); + void tile_weight_set(const int tile_index, const float val); + + String tile_name_get(const int tile_index); + void tile_name_set(const int tile_index, const String &val); + + int neighbour_data_add(const int n1, const int n2, const int n3, const int n4); + PoolIntArray neighbour_data_get(const int index); + void neighbour_data_remove(const int index); + void neighbour_data_set(const int index, const int n1, const int n2, const int n3, const int n4); + void set_tiles(const Vector &p_tiles); void set_neighbours(const Vector &p_neighbors); void generate_oriented_tile_ids(); - void generate_propagator(); static Vector get_tiles_weights(const Vector &tiles); @@ -111,4 +156,4 @@ private: Vector> oriented_tile_ids; }; -#endif // FAST_WFC_TILING_WFC_HPP_ +#endif