diff --git a/modules/wfc/overlapping_wfc.h b/modules/wfc/overlapping_wfc.h index 8c635eebf..7fbdf9609 100644 --- a/modules/wfc/overlapping_wfc.h +++ b/modules/wfc/overlapping_wfc.h @@ -43,7 +43,7 @@ private: const Array2D &input, const OverlappingWFCOptions &options, const int &seed, const std::pair>, Vector> &patterns, - const Vector, 4>> &propagator) : + const Vector &propagator) : input(input), options(options), patterns(patterns.first), wfc(options.periodic_output, seed, patterns.second, propagator, options.get_wave_height(), options.get_wave_width()) { // If necessary, the ground is set. if (options.ground) { @@ -156,8 +156,8 @@ private: // If agrees(pattern1, pattern2, dy, dx), then compatible[pattern1][direction] // contains pattern2, where direction is the direction defined by (dy, dx) // (see direction.hpp). - static Vector, 4>> generate_compatible(const Vector> &patterns) { - Vector, 4>> compatible = Vector, 4>>(patterns.size()); + static Vector generate_compatible(const Vector> &patterns) { + Vector compatible = Vector(patterns.size()); // Iterate on every dy, dx, pattern1 and pattern2 for (uint32_t pattern1 = 0; pattern1 < patterns.size(); pattern1++) { diff --git a/modules/wfc/propagator.cpp b/modules/wfc/propagator.cpp index 89d50a6a0..2a4df7715 100644 --- a/modules/wfc/propagator.cpp +++ b/modules/wfc/propagator.cpp @@ -2,13 +2,14 @@ #include "wave.h" void Propagator::init_compatible() { - std::array value; + CompatibilityEntry value; // We compute the number of pattern compatible in all directions. for (uint32_t y = 0; y < wave_height; y++) { for (uint32_t x = 0; x < wave_width; x++) { for (uint32_t pattern = 0; pattern < patterns_size; pattern++) { + for (int direction = 0; direction < 4; direction++) { - value[direction] = static_cast(propagator_state[pattern][get_opposite_direction(direction)].size()); + value.direction[direction] = static_cast(propagator_state[pattern].directions[get_opposite_direction(direction)].size()); } compatible.get(y, x, pattern) = value; @@ -47,7 +48,7 @@ void Propagator::propagate(Wave &wave) { // The index of the second cell, and the patterns compatible uint32_t i2 = x2 + y2 * wave.width; - const Vector &patterns = propagator_state[pattern][direction]; + const Vector &patterns = propagator_state[pattern].directions[direction]; // For every pattern that could be placed in that cell without being in // contradiction with pattern1 @@ -58,12 +59,12 @@ void Propagator::propagate(Wave &wave) { // We decrease the number of compatible patterns in the opposite // direction If the pattern was discarded from the wave, the element // is still negative, which is not a problem - std::array &value = compatible.get(y2, x2, pattern); - value[direction]--; + CompatibilityEntry &value = compatible.get(y2, x2, pattern); + value.direction[direction]--; // If the element was set to 0 with this operation, we need to remove // the pattern from the wave, and propagate the information - if (value[direction] == 0) { + if (value.direction[direction] == 0) { add_to_propagator(y2, x2, pattern); wave.set(i2, pattern, false); } diff --git a/modules/wfc/propagator.h b/modules/wfc/propagator.h index 7b6638fab..00a0f2a09 100644 --- a/modules/wfc/propagator.h +++ b/modules/wfc/propagator.h @@ -2,16 +2,19 @@ #define FAST_WFC_PROPAGATOR_HPP_ #include "array_3d.h" -#include "direction.h" -#include -#include #include "core/vector.h" +#include "direction.h" +#include class Wave; class Propagator { public: - using PropagatorState = Vector, 4>>; + struct PropagatorEntry { + Vector directions[4]; + }; + + using PropagatorState = Vector; private: const uint32_t patterns_size; @@ -28,12 +31,22 @@ private: // false. Vector> propagating; + struct CompatibilityEntry { + int direction[4]; + + CompatibilityEntry() { + for (int i = 0; i < 4; ++i) { + direction[i] = 0; + } + } + }; + // compatible.get(y, x, pattern)[direction] contains the number of patterns // present in the wave that can be placed in the cell next to (y,x) in the // opposite direction of direction without being in contradiction with pattern // placed in (y,x). If wave.get(y, x, pattern) is set to false, then // compatible.get(y, x, pattern) has every element negative or null - Array3D> compatible; + Array3D compatible; void init_compatible(); @@ -51,9 +64,9 @@ public: void add_to_propagator(uint32_t y, uint32_t x, uint32_t pattern) { // All the direction are set to 0, since the pattern cannot be set in (y,x). - std::array temp = {}; + CompatibilityEntry temp; compatible.get(y, x, pattern) = temp; - + propagating.push_back(std::tuple(y, x, pattern)); } diff --git a/modules/wfc/tiling_wfc.h b/modules/wfc/tiling_wfc.h index 73f169aa9..c39a31002 100644 --- a/modules/wfc/tiling_wfc.h +++ b/modules/wfc/tiling_wfc.h @@ -1,8 +1,8 @@ #ifndef FAST_WFC_TILING_WFC_HPP_ #define FAST_WFC_TILING_WFC_HPP_ -#include #include "core/vector.h" +#include #include "array_2d.h" #include "wfc.h" @@ -199,16 +199,30 @@ private: return { id_to_oriented_tile, oriented_tile_ids }; } + struct DensePropagatorHelper { + Vector directions[4]; + + void resize(const int size) { + for (int i = 0; i < 4; ++i) { + directions[i].resize(size); + directions[i].fill(false); + } + } + }; + // Generate the propagator which will be used in the wfc algorithm. - static Vector, 4>> generate_propagator( + static Vector generate_propagator( const Vector> &neighbors, Vector> tiles, Vector> id_to_oriented_tile, Vector> oriented_tile_ids) { - + size_t nb_oriented_tiles = id_to_oriented_tile.size(); - Vector, 4>> dense_propagator( - nb_oriented_tiles, { Vector(nb_oriented_tiles, false), Vector(nb_oriented_tiles, false), Vector(nb_oriented_tiles, false), Vector(nb_oriented_tiles, false) }); + Vector dense_propagator(nb_oriented_tiles, { Vector(nb_oriented_tiles, false), Vector(nb_oriented_tiles, false), Vector(nb_oriented_tiles, false), Vector(nb_oriented_tiles, false) }); + dense_propagator.resize(nb_oriented_tiles); + for (int i = 0; i < nb_oriented_tiles; ++i) { + dense_propagator.write[i].resize(nb_oriented_tiles); + } for (auto neighbor : neighbors) { uint32_t tile1 = std::get<0>(neighbor); @@ -240,7 +254,7 @@ private: add(7, 0); } - Vector, 4>> propagator(nb_oriented_tiles); + Vector propagator(nb_oriented_tiles); for (size_t i = 0; i < nb_oriented_tiles; ++i) { for (size_t j = 0; j < nb_oriented_tiles; ++j) {