mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-04-15 08:08:26 +02:00
Prefixed all member variables with _ in the wfc module.
This commit is contained in:
parent
d8938665f8
commit
3de05db75a
1
TODO.md
1
TODO.md
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
- Need to rework the readme. Also link to the sample repo. (https://github.com/Relintai/wfc_module_samples)
|
- Need to rework the readme. Also link to the sample repo. (https://github.com/Relintai/wfc_module_samples)
|
||||||
- TilingWaveFormCollapse should not generate the images themeslves, rather it should just use internal ids, and return those to you. It could store variants. -> a derived class chould be mamde that adds image generation on top, but in a friendlier way.
|
- TilingWaveFormCollapse should not generate the images themeslves, rather it should just use internal ids, and return those to you. It could store variants. -> a derived class chould be mamde that adds image generation on top, but in a friendlier way.
|
||||||
- All class variables should be previxed with "_".
|
|
||||||
- Array2D and 3D's getters and setters that need coordinates use a reversed order compared to everything in the engine. This is super dangerous, and should be changed. (Currently: get(y, x). Should be get(x, y)).
|
- Array2D and 3D's getters and setters that need coordinates use a reversed order compared to everything in the engine. This is super dangerous, and should be changed. (Currently: get(y, x). Should be get(x, y)).
|
||||||
- The classes need smaller fixes and touchups.
|
- The classes need smaller fixes and touchups.
|
||||||
- There are probably a few lingering bugs, as some examples give bad results.
|
- There are probably a few lingering bugs, as some examples give bad results.
|
||||||
|
@ -4,54 +4,54 @@
|
|||||||
#include "core/set.h"
|
#include "core/set.h"
|
||||||
|
|
||||||
bool OverlappingWaveFormCollapse::get_periodic_input() const {
|
bool OverlappingWaveFormCollapse::get_periodic_input() const {
|
||||||
return periodic_input;
|
return _periodic_input;
|
||||||
}
|
}
|
||||||
void OverlappingWaveFormCollapse::set_periodic_input(const bool val) {
|
void OverlappingWaveFormCollapse::set_periodic_input(const bool val) {
|
||||||
periodic_input = val;
|
_periodic_input = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_out_height() const {
|
int OverlappingWaveFormCollapse::get_out_height() const {
|
||||||
return out_height;
|
return _out_height;
|
||||||
}
|
}
|
||||||
void OverlappingWaveFormCollapse::set_out_height(const int val) {
|
void OverlappingWaveFormCollapse::set_out_height(const int val) {
|
||||||
out_height = val;
|
_out_height = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_out_width() const {
|
int OverlappingWaveFormCollapse::get_out_width() const {
|
||||||
return out_width;
|
return _out_width;
|
||||||
}
|
}
|
||||||
void OverlappingWaveFormCollapse::set_out_width(const int val) {
|
void OverlappingWaveFormCollapse::set_out_width(const int val) {
|
||||||
out_width = val;
|
_out_width = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_symmetry() const {
|
int OverlappingWaveFormCollapse::get_symmetry() const {
|
||||||
return symmetry;
|
return _symmetry;
|
||||||
}
|
}
|
||||||
void OverlappingWaveFormCollapse::set_symmetry(const int val) {
|
void OverlappingWaveFormCollapse::set_symmetry(const int val) {
|
||||||
symmetry = val;
|
_symmetry = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OverlappingWaveFormCollapse::get_ground() const {
|
bool OverlappingWaveFormCollapse::get_ground() const {
|
||||||
return ground;
|
return _ground;
|
||||||
}
|
}
|
||||||
void OverlappingWaveFormCollapse::set_ground(const bool val) {
|
void OverlappingWaveFormCollapse::set_ground(const bool val) {
|
||||||
ground = val;
|
_ground = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_pattern_size() const {
|
int OverlappingWaveFormCollapse::get_pattern_size() const {
|
||||||
return pattern_size;
|
return _pattern_size;
|
||||||
}
|
}
|
||||||
void OverlappingWaveFormCollapse::set_pattern_size(const int val) {
|
void OverlappingWaveFormCollapse::set_pattern_size(const int val) {
|
||||||
pattern_size = val;
|
_pattern_size = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_wave_height() const {
|
int OverlappingWaveFormCollapse::get_wave_height() const {
|
||||||
return periodic_output ? out_height : out_height - pattern_size + 1;
|
return _periodic_output ? _out_height : _out_height - _pattern_size + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get the wave width given these
|
//Get the wave width given these
|
||||||
int OverlappingWaveFormCollapse::get_wave_width() const {
|
int OverlappingWaveFormCollapse::get_wave_width() const {
|
||||||
return periodic_output ? out_width : out_width - pattern_size + 1;
|
return _periodic_output ? _out_width : _out_width - _pattern_size + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the WFC algorithm, and return the result if the algorithm succeeded.
|
// Run the WFC algorithm, and return the result if the algorithm succeeded.
|
||||||
@ -99,11 +99,11 @@ bool OverlappingWaveFormCollapse::set_pattern(const Array2D<int> &pattern, int i
|
|||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_ground_pattern_id() {
|
int OverlappingWaveFormCollapse::get_ground_pattern_id() {
|
||||||
// Get the pattern.
|
// Get the pattern.
|
||||||
Array2D<int> ground_pattern = input.get_sub_array(input.height - 1, input.width / 2, pattern_size, pattern_size);
|
Array2D<int> ground_pattern = _input.get_sub_array(_input.height - 1, _input.width / 2, _pattern_size, _pattern_size);
|
||||||
|
|
||||||
// Retrieve the id of the pattern.
|
// Retrieve the id of the pattern.
|
||||||
for (int i = 0; i < patterns.size(); i++) {
|
for (int i = 0; i < _patterns.size(); i++) {
|
||||||
if (ground_pattern == patterns[i]) {
|
if (ground_pattern == _patterns[i]) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,8 +112,8 @@ int OverlappingWaveFormCollapse::get_ground_pattern_id() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int OverlappingWaveFormCollapse::get_pattern_id(const Array2D<int> &pattern) {
|
int OverlappingWaveFormCollapse::get_pattern_id(const Array2D<int> &pattern) {
|
||||||
for (int i = 0; i < patterns.size(); ++i) {
|
for (int i = 0; i < _patterns.size(); ++i) {
|
||||||
if (patterns[i] == pattern) {
|
if (_patterns[i] == pattern) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ int OverlappingWaveFormCollapse::get_pattern_id(const Array2D<int> &pattern) {
|
|||||||
// Set the pattern at a specific position, given its pattern id
|
// Set the pattern at a specific position, given its pattern id
|
||||||
// pattern_id needs to be a valid pattern id, and i and j needs to be in the wave range
|
// pattern_id needs to be a valid pattern id, and i and j needs to be in the wave range
|
||||||
void OverlappingWaveFormCollapse::set_pattern(int pattern_id, int i, int j) {
|
void OverlappingWaveFormCollapse::set_pattern(int pattern_id, int i, int j) {
|
||||||
for (int p = 0; p < patterns.size(); p++) {
|
for (int p = 0; p < _patterns.size(); p++) {
|
||||||
if (pattern_id != p) {
|
if (pattern_id != p) {
|
||||||
remove_wave_pattern(i, j, p);
|
remove_wave_pattern(i, j, p);
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ void OverlappingWaveFormCollapse::set_pattern(int pattern_id, int i, int j) {
|
|||||||
void OverlappingWaveFormCollapse::init_patterns() {
|
void OverlappingWaveFormCollapse::init_patterns() {
|
||||||
LocalVector<Array2D<int>> patterns_id;
|
LocalVector<Array2D<int>> patterns_id;
|
||||||
|
|
||||||
patterns.clear();
|
_patterns.clear();
|
||||||
|
|
||||||
// The number of time a pattern is seen in the input image.
|
// The number of time a pattern is seen in the input image.
|
||||||
Vector<double> patterns_weight;
|
Vector<double> patterns_weight;
|
||||||
@ -144,16 +144,16 @@ void OverlappingWaveFormCollapse::init_patterns() {
|
|||||||
symmetries.resize(8);
|
symmetries.resize(8);
|
||||||
|
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
symmetries.write[i].resize(pattern_size, pattern_size);
|
symmetries.write[i].resize(_pattern_size, _pattern_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
int max_i = periodic_input ? input.height : input.height - pattern_size + 1;
|
int max_i = _periodic_input ? _input.height : _input.height - _pattern_size + 1;
|
||||||
int max_j = periodic_input ? input.width : input.width - pattern_size + 1;
|
int max_j = _periodic_input ? _input.width : _input.width - _pattern_size + 1;
|
||||||
|
|
||||||
for (int i = 0; i < max_i; i++) {
|
for (int i = 0; i < max_i; i++) {
|
||||||
for (int j = 0; j < max_j; j++) {
|
for (int j = 0; j < max_j; j++) {
|
||||||
// Compute the symmetries of every pattern in the image.
|
// Compute the symmetries of every pattern in the image.
|
||||||
symmetries.write[0].data = input.get_sub_array(i, j, pattern_size, pattern_size).data;
|
symmetries.write[0].data = _input.get_sub_array(i, j, _pattern_size, _pattern_size).data;
|
||||||
symmetries.write[1].data = symmetries[0].reflected().data;
|
symmetries.write[1].data = symmetries[0].reflected().data;
|
||||||
symmetries.write[2].data = symmetries[0].rotated().data;
|
symmetries.write[2].data = symmetries[0].rotated().data;
|
||||||
symmetries.write[3].data = symmetries[2].reflected().data;
|
symmetries.write[3].data = symmetries[2].reflected().data;
|
||||||
@ -163,8 +163,8 @@ void OverlappingWaveFormCollapse::init_patterns() {
|
|||||||
symmetries.write[7].data = symmetries[6].reflected().data;
|
symmetries.write[7].data = symmetries[6].reflected().data;
|
||||||
|
|
||||||
// The number of symmetries in the option class define which symetries will be used.
|
// The number of symmetries in the option class define which symetries will be used.
|
||||||
for (int k = 0; k < symmetry; k++) {
|
for (int k = 0; k < _symmetry; k++) {
|
||||||
int indx = patterns.size();
|
int indx = _patterns.size();
|
||||||
|
|
||||||
for (uint32_t h = 0; h < patterns_id.size(); ++h) {
|
for (uint32_t h = 0; h < patterns_id.size(); ++h) {
|
||||||
if (patterns_id[h] == symmetries[k]) {
|
if (patterns_id[h] == symmetries[k]) {
|
||||||
@ -173,11 +173,11 @@ void OverlappingWaveFormCollapse::init_patterns() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indx != patterns.size()) {
|
if (indx != _patterns.size()) {
|
||||||
// If the pattern already exist, we just have to increase its number of appearance.
|
// If the pattern already exist, we just have to increase its number of appearance.
|
||||||
patterns_weight.write[indx] += 1;
|
patterns_weight.write[indx] += 1;
|
||||||
} else {
|
} else {
|
||||||
patterns.push_back(symmetries[k]);
|
_patterns.push_back(symmetries[k]);
|
||||||
patterns_weight.push_back(1);
|
patterns_weight.push_back(1);
|
||||||
patterns_id.push_back(symmetries[k]);
|
patterns_id.push_back(symmetries[k]);
|
||||||
}
|
}
|
||||||
@ -214,13 +214,13 @@ bool OverlappingWaveFormCollapse::agrees(const Array2D<int> &pattern1, const Arr
|
|||||||
// (see direction.hpp).
|
// (see direction.hpp).
|
||||||
void OverlappingWaveFormCollapse::generate_compatible() {
|
void OverlappingWaveFormCollapse::generate_compatible() {
|
||||||
Vector<WaveFormCollapse::PropagatorStateEntry> compatible;
|
Vector<WaveFormCollapse::PropagatorStateEntry> compatible;
|
||||||
compatible.resize(patterns.size());
|
compatible.resize(_patterns.size());
|
||||||
|
|
||||||
// Iterate on every dy, dx, pattern1 and pattern2
|
// Iterate on every dy, dx, pattern1 and pattern2
|
||||||
for (int pattern1 = 0; pattern1 < patterns.size(); pattern1++) {
|
for (int pattern1 = 0; pattern1 < _patterns.size(); pattern1++) {
|
||||||
for (int direction = 0; direction < 4; direction++) {
|
for (int direction = 0; direction < 4; direction++) {
|
||||||
for (int pattern2 = 0; pattern2 < patterns.size(); pattern2++) {
|
for (int pattern2 = 0; pattern2 < _patterns.size(); pattern2++) {
|
||||||
if (agrees(patterns[pattern1], patterns[pattern2], DIRECTIONS_Y[direction], DIRECTIONS_X[direction])) {
|
if (agrees(_patterns[pattern1], _patterns[pattern2], DIRECTIONS_Y[direction], DIRECTIONS_X[direction])) {
|
||||||
compatible.write[pattern1].directions[direction].push_back(pattern2);
|
compatible.write[pattern1].directions[direction].push_back(pattern2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -232,40 +232,40 @@ void OverlappingWaveFormCollapse::generate_compatible() {
|
|||||||
|
|
||||||
// Transform a 2D array containing the patterns id to a 2D array containing the pixels.
|
// Transform a 2D array containing the patterns id to a 2D array containing the pixels.
|
||||||
Array2D<int> OverlappingWaveFormCollapse::to_image(const Array2D<int> &output_patterns) const {
|
Array2D<int> OverlappingWaveFormCollapse::to_image(const Array2D<int> &output_patterns) const {
|
||||||
Array2D<int> output(out_height, out_width);
|
Array2D<int> output(_out_height, _out_width);
|
||||||
|
|
||||||
if (periodic_output) {
|
if (_periodic_output) {
|
||||||
for (int y = 0; y < get_wave_height(); y++) {
|
for (int y = 0; y < get_wave_height(); y++) {
|
||||||
for (int x = 0; x < get_wave_width(); x++) {
|
for (int x = 0; x < get_wave_width(); x++) {
|
||||||
output.get(y, x) = patterns[output_patterns.get(y, x)].get(0, 0);
|
output.get(y, x) = _patterns[output_patterns.get(y, x)].get(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int y = 0; y < get_wave_height(); y++) {
|
for (int y = 0; y < get_wave_height(); y++) {
|
||||||
for (int x = 0; x < get_wave_width(); x++) {
|
for (int x = 0; x < get_wave_width(); x++) {
|
||||||
output.get(y, x) = patterns[output_patterns.get(y, x)].get(0, 0);
|
output.get(y, x) = _patterns[output_patterns.get(y, x)].get(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int y = 0; y < get_wave_height(); y++) {
|
for (int y = 0; y < get_wave_height(); y++) {
|
||||||
const Array2D<int> &pattern = patterns[output_patterns.get(y, get_wave_width() - 1)];
|
const Array2D<int> &pattern = _patterns[output_patterns.get(y, get_wave_width() - 1)];
|
||||||
for (int dx = 1; dx < pattern_size; dx++) {
|
for (int dx = 1; dx < _pattern_size; dx++) {
|
||||||
output.get(y, get_wave_width() - 1 + dx) = pattern.get(0, dx);
|
output.get(y, get_wave_width() - 1 + dx) = pattern.get(0, dx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < get_wave_width(); x++) {
|
for (int x = 0; x < get_wave_width(); x++) {
|
||||||
const Array2D<int> &pattern = patterns[output_patterns.get(get_wave_height() - 1, x)];
|
const Array2D<int> &pattern = _patterns[output_patterns.get(get_wave_height() - 1, x)];
|
||||||
for (int dy = 1; dy < pattern_size; dy++) {
|
for (int dy = 1; dy < _pattern_size; dy++) {
|
||||||
output.get(get_wave_height() - 1 + dy, x) =
|
output.get(get_wave_height() - 1 + dy, x) =
|
||||||
pattern.get(dy, 0);
|
pattern.get(dy, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Array2D<int> &pattern = patterns[output_patterns.get(get_wave_height() - 1, get_wave_width() - 1)];
|
const Array2D<int> &pattern = _patterns[output_patterns.get(get_wave_height() - 1, get_wave_width() - 1)];
|
||||||
|
|
||||||
for (int dy = 1; dy < pattern_size; dy++) {
|
for (int dy = 1; dy < _pattern_size; dy++) {
|
||||||
for (int dx = 1; dx < pattern_size; dx++) {
|
for (int dx = 1; dx < _pattern_size; dx++) {
|
||||||
output.get(get_wave_height() - 1 + dy, get_wave_width() - 1 + dx) = pattern.get(dy, dx);
|
output.get(get_wave_height() - 1 + dy, get_wave_width() - 1 + dx) = pattern.get(dy, dx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,18 +283,18 @@ void OverlappingWaveFormCollapse::initialize() {
|
|||||||
WaveFormCollapse::initialize();
|
WaveFormCollapse::initialize();
|
||||||
|
|
||||||
// If necessary, the ground is set.
|
// If necessary, the ground is set.
|
||||||
if (ground) {
|
if (_ground) {
|
||||||
init_ground();
|
init_ground();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlappingWaveFormCollapse::OverlappingWaveFormCollapse() {
|
OverlappingWaveFormCollapse::OverlappingWaveFormCollapse() {
|
||||||
periodic_input = true;
|
_periodic_input = true;
|
||||||
out_height = 0;
|
_out_height = 0;
|
||||||
out_width = 0;
|
_out_width = 0;
|
||||||
symmetry = 8;
|
_symmetry = 8;
|
||||||
ground = false;
|
_ground = false;
|
||||||
pattern_size = 0;
|
_pattern_size = 0;
|
||||||
}
|
}
|
||||||
OverlappingWaveFormCollapse::~OverlappingWaveFormCollapse() {
|
OverlappingWaveFormCollapse::~OverlappingWaveFormCollapse() {
|
||||||
}
|
}
|
||||||
|
@ -57,14 +57,14 @@ protected:
|
|||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<Array2D<int>> patterns;
|
Vector<Array2D<int>> _patterns;
|
||||||
|
|
||||||
bool periodic_input;
|
bool _periodic_input;
|
||||||
int out_height;
|
int _out_height;
|
||||||
int out_width;
|
int _out_width;
|
||||||
int symmetry;
|
int _symmetry;
|
||||||
bool ground;
|
bool _ground;
|
||||||
int pattern_size;
|
int _pattern_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -166,122 +166,122 @@ Tile::Tile(const PoolIntArray &p_data, const int width, const int height, WaveFo
|
|||||||
}
|
}
|
||||||
|
|
||||||
int TilingWaveFormCollapse::tile_add_generated(const PoolIntArray &data, const int width, const int height, const WaveFormCollapse::Symmetry symmetry, const float 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));
|
_tiles.push_back(Tile(data, width, height, symmetry, weight));
|
||||||
|
|
||||||
return tiles.size() - 1;
|
return _tiles.size() - 1;
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_add(const WaveFormCollapse::Symmetry symmetry, const float weight) {
|
int TilingWaveFormCollapse::tile_add(const WaveFormCollapse::Symmetry symmetry, const float weight) {
|
||||||
tiles.push_back(Tile(symmetry, weight));
|
_tiles.push_back(Tile(symmetry, weight));
|
||||||
|
|
||||||
return tiles.size() - 1;
|
return _tiles.size() - 1;
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_create() {
|
int TilingWaveFormCollapse::tile_create() {
|
||||||
tiles.push_back(Tile());
|
_tiles.push_back(Tile());
|
||||||
|
|
||||||
return tiles.size() - 1;
|
return _tiles.size() - 1;
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::tile_remove(const int tile_index) {
|
void TilingWaveFormCollapse::tile_remove(const int tile_index) {
|
||||||
ERR_FAIL_INDEX(tile_index, tiles.size());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.remove(tile_index);
|
_tiles.remove(tile_index);
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_count_get() {
|
int TilingWaveFormCollapse::tile_count_get() {
|
||||||
return tiles.size();
|
return _tiles.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilingWaveFormCollapse::tile_data_add(const int tile_index, const PoolIntArray &data, const int width, const int height) {
|
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());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
Array2D<int> d(data, height, width);
|
Array2D<int> d(data, height, width);
|
||||||
|
|
||||||
tiles.write[tile_index].data.push_back(d);
|
_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) {
|
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());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].set_generate_data(data, width, height);
|
_tiles.write[tile_index].set_generate_data(data, width, height);
|
||||||
}
|
}
|
||||||
PoolIntArray TilingWaveFormCollapse::tile_data_get(const int tile_index, const int data_index) {
|
PoolIntArray TilingWaveFormCollapse::tile_data_get(const int tile_index, const int data_index) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), PoolIntArray());
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), PoolIntArray());
|
||||||
|
|
||||||
return tiles.write[tile_index].data_get(data_index);
|
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) {
|
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());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].data_set(data_index, data, width, height);
|
_tiles.write[tile_index].data_set(data_index, data, width, height);
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::tile_data_remove(const int tile_index, const int data_index) {
|
void TilingWaveFormCollapse::tile_data_remove(const int tile_index, const int data_index) {
|
||||||
ERR_FAIL_INDEX(tile_index, tiles.size());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].data_remove(data_index);
|
_tiles.write[tile_index].data_remove(data_index);
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::tile_data_clear(const int tile_index) {
|
void TilingWaveFormCollapse::tile_data_clear(const int tile_index) {
|
||||||
ERR_FAIL_INDEX(tile_index, tiles.size());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].data.clear();
|
_tiles.write[tile_index].data.clear();
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_data_count_get(const int tile_index) {
|
int TilingWaveFormCollapse::tile_data_count_get(const int tile_index) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0);
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), 0);
|
||||||
|
|
||||||
return tiles[tile_index].data.size();
|
return _tiles[tile_index].data.size();
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_data_required_count_get(const int tile_index) {
|
int TilingWaveFormCollapse::tile_data_required_count_get(const int tile_index) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0);
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), 0);
|
||||||
|
|
||||||
int symm_indx = static_cast<int>(tiles[tile_index].symmetry);
|
int symm_indx = static_cast<int>(_tiles[tile_index].symmetry);
|
||||||
|
|
||||||
return Tile::ROTATION_MAP[symm_indx][0];
|
return Tile::ROTATION_MAP[symm_indx][0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int TilingWaveFormCollapse::tile_width_get(const int tile_index, const int data_index) {
|
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(tile_index, _tiles.size(), 0);
|
||||||
ERR_FAIL_INDEX_V(data_index, tiles[tile_index].data.size(), 0);
|
ERR_FAIL_INDEX_V(data_index, _tiles[tile_index].data.size(), 0);
|
||||||
|
|
||||||
return tiles[tile_index].data[data_index].width;
|
return _tiles[tile_index].data[data_index].width;
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_height_get(const int tile_index, const int data_index) {
|
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(tile_index, _tiles.size(), 0);
|
||||||
ERR_FAIL_INDEX_V(data_index, tiles[tile_index].data.size(), 0);
|
ERR_FAIL_INDEX_V(data_index, _tiles[tile_index].data.size(), 0);
|
||||||
|
|
||||||
return tiles[tile_index].data[data_index].height;
|
return _tiles[tile_index].data[data_index].height;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaveFormCollapse::Symmetry TilingWaveFormCollapse::tile_symmetry_get(const int tile_index) {
|
WaveFormCollapse::Symmetry TilingWaveFormCollapse::tile_symmetry_get(const int tile_index) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), WaveFormCollapse::SYMMETRY_X);
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), WaveFormCollapse::SYMMETRY_X);
|
||||||
|
|
||||||
return tiles[tile_index].symmetry;
|
return _tiles[tile_index].symmetry;
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::tile_symmetry_set(const int tile_index, const WaveFormCollapse::Symmetry val) {
|
void TilingWaveFormCollapse::tile_symmetry_set(const int tile_index, const WaveFormCollapse::Symmetry val) {
|
||||||
ERR_FAIL_INDEX(tile_index, tiles.size());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].symmetry = val;
|
_tiles.write[tile_index].symmetry = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
float TilingWaveFormCollapse::tile_weight_get(const int tile_index) {
|
float TilingWaveFormCollapse::tile_weight_get(const int tile_index) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), 0);
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), 0);
|
||||||
|
|
||||||
return tiles[tile_index].weight;
|
return _tiles[tile_index].weight;
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::tile_weight_set(const int tile_index, const float val) {
|
void TilingWaveFormCollapse::tile_weight_set(const int tile_index, const float val) {
|
||||||
ERR_FAIL_INDEX(tile_index, tiles.size());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].weight = val;
|
_tiles.write[tile_index].weight = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
String TilingWaveFormCollapse::tile_name_get(const int tile_index) {
|
String TilingWaveFormCollapse::tile_name_get(const int tile_index) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), String());
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), String());
|
||||||
|
|
||||||
return tiles[tile_index].name;
|
return _tiles[tile_index].name;
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::tile_name_set(const int tile_index, const String &val) {
|
void TilingWaveFormCollapse::tile_name_set(const int tile_index, const String &val) {
|
||||||
ERR_FAIL_INDEX(tile_index, tiles.size());
|
ERR_FAIL_INDEX(tile_index, _tiles.size());
|
||||||
|
|
||||||
tiles.write[tile_index].name = val;
|
_tiles.write[tile_index].name = val;
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::tile_index_get(const String &tile_name) {
|
int TilingWaveFormCollapse::tile_index_get(const String &tile_name) {
|
||||||
for (int i = 0; i < tiles.size(); ++i) {
|
for (int i = 0; i < _tiles.size(); ++i) {
|
||||||
if (tiles[i].name == tile_name) {
|
if (_tiles[i].name == tile_name) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -295,9 +295,9 @@ int TilingWaveFormCollapse::neighbour_data_add(const int left, const int left_or
|
|||||||
|
|
||||||
NeighbourData d(left, left_orientation, right, right_orientation);
|
NeighbourData d(left, left_orientation, right, right_orientation);
|
||||||
|
|
||||||
neighbors.push_back(d);
|
_neighbors.push_back(d);
|
||||||
|
|
||||||
return neighbors.size() - 1;
|
return _neighbors.size() - 1;
|
||||||
}
|
}
|
||||||
int TilingWaveFormCollapse::neighbour_data_add_str(const String &left, const int left_orientation, const String &right, const int right_orientation) {
|
int TilingWaveFormCollapse::neighbour_data_add_str(const String &left, const int left_orientation, const String &right, const int right_orientation) {
|
||||||
int left_index = tile_index_get(left);
|
int left_index = tile_index_get(left);
|
||||||
@ -310,9 +310,9 @@ int TilingWaveFormCollapse::neighbour_data_add_str(const String &left, const int
|
|||||||
}
|
}
|
||||||
|
|
||||||
PoolIntArray TilingWaveFormCollapse::neighbour_data_get(const int index) {
|
PoolIntArray TilingWaveFormCollapse::neighbour_data_get(const int index) {
|
||||||
ERR_FAIL_INDEX_V(index, neighbors.size(), PoolIntArray());
|
ERR_FAIL_INDEX_V(index, _neighbors.size(), PoolIntArray());
|
||||||
|
|
||||||
const NeighbourData &d = neighbors[index];
|
const NeighbourData &d = _neighbors[index];
|
||||||
|
|
||||||
PoolIntArray p;
|
PoolIntArray p;
|
||||||
p.resize(4);
|
p.resize(4);
|
||||||
@ -328,20 +328,20 @@ PoolIntArray TilingWaveFormCollapse::neighbour_data_get(const int index) {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
void TilingWaveFormCollapse::neighbour_data_remove(const int index) {
|
void TilingWaveFormCollapse::neighbour_data_remove(const int index) {
|
||||||
ERR_FAIL_INDEX(index, neighbors.size());
|
ERR_FAIL_INDEX(index, _neighbors.size());
|
||||||
|
|
||||||
neighbors.remove(index);
|
_neighbors.remove(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilingWaveFormCollapse::neighbour_data_set(const int index, const int left, const int left_orientation, const int right, const int right_orientation) {
|
void TilingWaveFormCollapse::neighbour_data_set(const int index, const int left, const int left_orientation, const int right, const int right_orientation) {
|
||||||
ERR_FAIL_INDEX(index, neighbors.size());
|
ERR_FAIL_INDEX(index, _neighbors.size());
|
||||||
|
|
||||||
ERR_FAIL_COND(!neighbour_data_validate(left, left_orientation));
|
ERR_FAIL_COND(!neighbour_data_validate(left, left_orientation));
|
||||||
ERR_FAIL_COND(!neighbour_data_validate(right, right_orientation));
|
ERR_FAIL_COND(!neighbour_data_validate(right, right_orientation));
|
||||||
|
|
||||||
NeighbourData d(left, left_orientation, right, right_orientation);
|
NeighbourData d(left, left_orientation, right, right_orientation);
|
||||||
|
|
||||||
neighbors.write[index] = d;
|
_neighbors.write[index] = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilingWaveFormCollapse::neighbour_data_set_str(const int index, const String &left, const int left_orientation, const String &right, const int right_orientation) {
|
void TilingWaveFormCollapse::neighbour_data_set_str(const int index, const String &left, const int left_orientation, const String &right, const int right_orientation) {
|
||||||
@ -355,13 +355,13 @@ void TilingWaveFormCollapse::neighbour_data_set_str(const int index, const Strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TilingWaveFormCollapse::neighbour_data_validate(const int tile_index, const int orientation) {
|
bool TilingWaveFormCollapse::neighbour_data_validate(const int tile_index, const int orientation) {
|
||||||
ERR_FAIL_INDEX_V(tile_index, tiles.size(), false);
|
ERR_FAIL_INDEX_V(tile_index, _tiles.size(), false);
|
||||||
|
|
||||||
if (orientation < 0) {
|
if (orientation < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int symm_indx = static_cast<int>(tiles[tile_index].symmetry);
|
int symm_indx = static_cast<int>(_tiles[tile_index].symmetry);
|
||||||
|
|
||||||
if (orientation >= Tile::ROTATION_MAP[symm_indx][0]) {
|
if (orientation >= Tile::ROTATION_MAP[symm_indx][0]) {
|
||||||
return false;
|
return false;
|
||||||
@ -379,38 +379,38 @@ bool TilingWaveFormCollapse::neighbour_data_validate_str(const String &tile_name
|
|||||||
|
|
||||||
// Returns false if the given tile and orientation does not exist, or if the coordinates are not in the wave
|
// 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) {
|
bool TilingWaveFormCollapse::set_tile(int tile_id, int orientation, int i, int j) {
|
||||||
if (tile_id >= static_cast<int>(oriented_tile_ids.size()) ||
|
if (tile_id >= static_cast<int>(_oriented_tile_ids.size()) ||
|
||||||
orientation >= static_cast<int>(oriented_tile_ids[tile_id].size()) ||
|
orientation >= static_cast<int>(_oriented_tile_ids[tile_id].size()) ||
|
||||||
i >= _wave_height || j >= _wave_width) {
|
i >= _wave_height || j >= _wave_width) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int oriented_tile_id = oriented_tile_ids[tile_id][orientation];
|
int oriented_tile_id = _oriented_tile_ids[tile_id][orientation];
|
||||||
set_tile(oriented_tile_id, i, j);
|
set_tile(oriented_tile_id, i, j);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilingWaveFormCollapse::set_tiles(const Vector<Tile> &p_tiles) {
|
void TilingWaveFormCollapse::set_tiles(const Vector<Tile> &p_tiles) {
|
||||||
tiles = p_tiles;
|
_tiles = p_tiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TilingWaveFormCollapse::set_neighbours(const Vector<NeighbourData> &p_neighbors) {
|
void TilingWaveFormCollapse::set_neighbours(const Vector<NeighbourData> &p_neighbors) {
|
||||||
neighbors = p_neighbors;
|
_neighbors = p_neighbors;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate mapping from id to oriented tiles and vice versa.
|
// Generate mapping from id to oriented tiles and vice versa.
|
||||||
void TilingWaveFormCollapse::generate_oriented_tile_ids() {
|
void TilingWaveFormCollapse::generate_oriented_tile_ids() {
|
||||||
id_to_oriented_tile.clear();
|
_id_to_oriented_tile.clear();
|
||||||
oriented_tile_ids.clear();
|
_oriented_tile_ids.clear();
|
||||||
|
|
||||||
int id = 0;
|
int id = 0;
|
||||||
for (int i = 0; i < tiles.size(); i++) {
|
for (int i = 0; i < _tiles.size(); i++) {
|
||||||
oriented_tile_ids.push_back(Vector<int>());
|
_oriented_tile_ids.push_back(Vector<int>());
|
||||||
|
|
||||||
for (int j = 0; j < tiles[i].data.size(); j++) {
|
for (int j = 0; j < _tiles[i].data.size(); j++) {
|
||||||
id_to_oriented_tile.push_back(IdToTilePair(i, j));
|
_id_to_oriented_tile.push_back(IdToTilePair(i, j));
|
||||||
oriented_tile_ids.write[i].push_back(id);
|
_oriented_tile_ids.write[i].push_back(id);
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,7 +418,7 @@ void TilingWaveFormCollapse::generate_oriented_tile_ids() {
|
|||||||
|
|
||||||
// Generate the propagator which will be used in the wfc algorithm.
|
// Generate the propagator which will be used in the wfc algorithm.
|
||||||
void TilingWaveFormCollapse::generate_propagator() {
|
void TilingWaveFormCollapse::generate_propagator() {
|
||||||
int nb_oriented_tiles = id_to_oriented_tile.size();
|
int nb_oriented_tiles = _id_to_oriented_tile.size();
|
||||||
|
|
||||||
Vector<DensePropagatorHelper> dense_propagator;
|
Vector<DensePropagatorHelper> dense_propagator;
|
||||||
dense_propagator.resize(nb_oriented_tiles);
|
dense_propagator.resize(nb_oriented_tiles);
|
||||||
@ -426,14 +426,14 @@ void TilingWaveFormCollapse::generate_propagator() {
|
|||||||
dense_propagator.write[i].resize(nb_oriented_tiles);
|
dense_propagator.write[i].resize(nb_oriented_tiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = neighbors.size();
|
int size = _neighbors.size();
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
const NeighbourData &neighbour = neighbors[i];
|
const NeighbourData &neighbour = _neighbors[i];
|
||||||
|
|
||||||
int tile1 = neighbour.data[0];
|
int tile1 = neighbour.data[0];
|
||||||
int tile2 = neighbour.data[2];
|
int tile2 = neighbour.data[2];
|
||||||
Tile::ActionMap action_map1 = Tile::generate_action_map(tiles[tile1].symmetry);
|
Tile::ActionMap action_map1 = Tile::generate_action_map(_tiles[tile1].symmetry);
|
||||||
Tile::ActionMap action_map2 = Tile::generate_action_map(tiles[tile2].symmetry);
|
Tile::ActionMap action_map2 = Tile::generate_action_map(_tiles[tile2].symmetry);
|
||||||
|
|
||||||
generate_propagator_add_helper(action_map1, action_map2, &dense_propagator, neighbour, 0, 2);
|
generate_propagator_add_helper(action_map1, action_map2, &dense_propagator, neighbour, 0, 2);
|
||||||
generate_propagator_add_helper(action_map1, action_map2, &dense_propagator, neighbour, 1, 0);
|
generate_propagator_add_helper(action_map1, action_map2, &dense_propagator, neighbour, 1, 0);
|
||||||
@ -477,7 +477,7 @@ Vector<double> TilingWaveFormCollapse::get_tiles_weights(const Vector<Tile> &til
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TilingWaveFormCollapse::set_tile(int tile_id, int i, int j) {
|
void TilingWaveFormCollapse::set_tile(int tile_id, int i, int j) {
|
||||||
for (int p = 0; p < id_to_oriented_tile.size(); p++) {
|
for (int p = 0; p < _id_to_oriented_tile.size(); p++) {
|
||||||
if (tile_id != static_cast<int>(p)) {
|
if (tile_id != static_cast<int>(p)) {
|
||||||
remove_wave_pattern(i, j, p);
|
remove_wave_pattern(i, j, p);
|
||||||
}
|
}
|
||||||
@ -496,22 +496,22 @@ Array2D<int> TilingWaveFormCollapse::run() {
|
|||||||
|
|
||||||
// Translate the generic WFC result into the image result
|
// Translate the generic WFC result into the image result
|
||||||
Array2D<int> TilingWaveFormCollapse::id_to_tiling(Array2D<int> ids) {
|
Array2D<int> TilingWaveFormCollapse::id_to_tiling(Array2D<int> ids) {
|
||||||
int size = tiles[0].data[0].height;
|
int size = _tiles[0].data[0].height;
|
||||||
Array2D<int> tiling(size * ids.height, size * ids.width);
|
Array2D<int> tiling(size * ids.height, size * ids.width);
|
||||||
|
|
||||||
for (int i = 0; i < ids.height; i++) {
|
for (int i = 0; i < ids.height; i++) {
|
||||||
for (int j = 0; j < ids.width; j++) {
|
for (int j = 0; j < ids.width; j++) {
|
||||||
int id = ids.get(i, j);
|
int id = ids.get(i, j);
|
||||||
|
|
||||||
if (id < 0 || id >= id_to_oriented_tile.size()) {
|
if (id < 0 || id >= _id_to_oriented_tile.size()) {
|
||||||
id = 0;
|
id = 0;
|
||||||
|
|
||||||
ERR_PRINT("id < 0 || id >= id_to_oriented_tile.size()");
|
ERR_PRINT("id < 0 || id >= id_to_oriented_tile.size()");
|
||||||
}
|
}
|
||||||
|
|
||||||
IdToTilePair oriented_tile = id_to_oriented_tile[id];
|
IdToTilePair oriented_tile = _id_to_oriented_tile[id];
|
||||||
|
|
||||||
const Array2D<int> &tile = tiles[oriented_tile.id].data[oriented_tile.oriented_tile];
|
const Array2D<int> &tile = _tiles[oriented_tile.id].data[oriented_tile.oriented_tile];
|
||||||
|
|
||||||
for (int y = 0; y < size; y++) {
|
for (int y = 0; y < size; y++) {
|
||||||
for (int x = 0; x < size; x++) {
|
for (int x = 0; x < size; x++) {
|
||||||
@ -525,12 +525,12 @@ Array2D<int> TilingWaveFormCollapse::id_to_tiling(Array2D<int> ids) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TilingWaveFormCollapse::validate() {
|
bool TilingWaveFormCollapse::validate() {
|
||||||
for (int i = 0; i < tiles.size(); ++i) {
|
for (int i = 0; i < _tiles.size(); ++i) {
|
||||||
int symm_indx = static_cast<int>(tiles[i].symmetry);
|
int symm_indx = static_cast<int>(_tiles[i].symmetry);
|
||||||
|
|
||||||
int symm_req_count = Tile::ROTATION_MAP[symm_indx][0];
|
int symm_req_count = Tile::ROTATION_MAP[symm_indx][0];
|
||||||
|
|
||||||
if (tiles[i].data.size() != symm_req_count) {
|
if (_tiles[i].data.size() != symm_req_count) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -541,7 +541,7 @@ bool TilingWaveFormCollapse::validate() {
|
|||||||
void TilingWaveFormCollapse::initialize() {
|
void TilingWaveFormCollapse::initialize() {
|
||||||
ERR_FAIL_COND(!validate());
|
ERR_FAIL_COND(!validate());
|
||||||
|
|
||||||
set_pattern_frequencies(get_tiles_weights(tiles));
|
set_pattern_frequencies(get_tiles_weights(_tiles));
|
||||||
generate_oriented_tile_ids();
|
generate_oriented_tile_ids();
|
||||||
generate_propagator();
|
generate_propagator();
|
||||||
|
|
||||||
@ -603,8 +603,8 @@ void TilingWaveFormCollapse::generate_propagator_add_helper(const Tile::ActionMa
|
|||||||
|
|
||||||
int temp_orientation1 = action_map1.map[action][orientation1];
|
int temp_orientation1 = action_map1.map[action][orientation1];
|
||||||
int temp_orientation2 = action_map2.map[action][orientation2];
|
int temp_orientation2 = action_map2.map[action][orientation2];
|
||||||
int oriented_tile_id1 = oriented_tile_ids[tile1][temp_orientation1];
|
int oriented_tile_id1 = _oriented_tile_ids[tile1][temp_orientation1];
|
||||||
int oriented_tile_id2 = oriented_tile_ids[tile2][temp_orientation2];
|
int oriented_tile_id2 = _oriented_tile_ids[tile2][temp_orientation2];
|
||||||
dense_propagator->write[oriented_tile_id1].directions[direction].write[oriented_tile_id2] = true;
|
dense_propagator->write[oriented_tile_id1].directions[direction].write[oriented_tile_id2] = true;
|
||||||
direction = get_opposite_direction(direction);
|
direction = get_opposite_direction(direction);
|
||||||
dense_propagator->write[oriented_tile_id2].directions[direction].write[oriented_tile_id1] = true;
|
dense_propagator->write[oriented_tile_id2].directions[direction].write[oriented_tile_id1] = true;
|
||||||
|
@ -162,11 +162,11 @@ private:
|
|||||||
const NeighbourData &neighbour,
|
const NeighbourData &neighbour,
|
||||||
int action, int direction);
|
int action, int direction);
|
||||||
|
|
||||||
Vector<Tile> tiles;
|
Vector<Tile> _tiles;
|
||||||
Vector<NeighbourData> neighbors;
|
Vector<NeighbourData> _neighbors;
|
||||||
|
|
||||||
Vector<IdToTilePair> id_to_oriented_tile;
|
Vector<IdToTilePair> _id_to_oriented_tile;
|
||||||
Vector<Vector<int>> oriented_tile_ids;
|
Vector<Vector<int>> _oriented_tile_ids;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -56,14 +56,14 @@ void WaveFormCollapse::set_wave_height(const int val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool WaveFormCollapse::get_periodic_output() const {
|
bool WaveFormCollapse::get_periodic_output() const {
|
||||||
return periodic_output;
|
return _periodic_output;
|
||||||
}
|
}
|
||||||
void WaveFormCollapse::set_periodic_output(const bool val) {
|
void WaveFormCollapse::set_periodic_output(const bool val) {
|
||||||
periodic_output = val;
|
_periodic_output = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFormCollapse::set_seed(const int seed) {
|
void WaveFormCollapse::set_seed(const int seed) {
|
||||||
gen.seed(seed);
|
_gen.seed(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFormCollapse::set_wave_size(int p_width, int p_height) {
|
void WaveFormCollapse::set_wave_size(int p_width, int p_height) {
|
||||||
@ -77,24 +77,24 @@ void WaveFormCollapse::init_wave() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaveFormCollapse::set_propagator_state(const Vector<PropagatorStateEntry> &p_propagator_state) {
|
void WaveFormCollapse::set_propagator_state(const Vector<PropagatorStateEntry> &p_propagator_state) {
|
||||||
propagator_state = p_propagator_state;
|
_propagator_state = p_propagator_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFormCollapse::set_pattern_frequencies(const Vector<double> &p_patterns_frequencies, const bool p_normalize) {
|
void WaveFormCollapse::set_pattern_frequencies(const Vector<double> &p_patterns_frequencies, const bool p_normalize) {
|
||||||
patterns_frequencies = p_patterns_frequencies;
|
_patterns_frequencies = p_patterns_frequencies;
|
||||||
|
|
||||||
if (p_normalize) {
|
if (p_normalize) {
|
||||||
normalize(patterns_frequencies);
|
normalize(_patterns_frequencies);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFormCollapse::set_input(const PoolIntArray &p_data, int p_width, int p_height) {
|
void WaveFormCollapse::set_input(const PoolIntArray &p_data, int p_width, int p_height) {
|
||||||
input.resize(p_height, p_width);
|
_input.resize(p_height, p_width);
|
||||||
|
|
||||||
ERR_FAIL_COND(input.data.size() != p_data.size());
|
ERR_FAIL_COND(_input.data.size() != p_data.size());
|
||||||
|
|
||||||
int *w = input.data.ptrw();
|
int *w = _input.data.ptrw();
|
||||||
int s = input.data.size();
|
int s = _input.data.size();
|
||||||
|
|
||||||
PoolIntArray::Read r = p_data.read();
|
PoolIntArray::Read r = p_data.read();
|
||||||
|
|
||||||
@ -160,16 +160,16 @@ WaveFormCollapse::ObserveStatus WaveFormCollapse::observe() {
|
|||||||
|
|
||||||
// Choose an element according to the pattern distribution
|
// Choose an element according to the pattern distribution
|
||||||
double s = 0;
|
double s = 0;
|
||||||
for (int k = 0; k < patterns_frequencies.size(); k++) {
|
for (int k = 0; k < _patterns_frequencies.size(); k++) {
|
||||||
s += wave_get(argmin, k) ? patterns_frequencies[k] : 0;
|
s += wave_get(argmin, k) ? _patterns_frequencies[k] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
double random_value = gen.random(0.0, s);
|
double random_value = _gen.random(0.0, s);
|
||||||
|
|
||||||
int chosen_value = patterns_frequencies.size() - 1;
|
int chosen_value = _patterns_frequencies.size() - 1;
|
||||||
|
|
||||||
for (int k = 0; k < patterns_frequencies.size(); k++) {
|
for (int k = 0; k < _patterns_frequencies.size(); k++) {
|
||||||
random_value -= wave_get(argmin, k) ? patterns_frequencies[k] : 0;
|
random_value -= wave_get(argmin, k) ? _patterns_frequencies[k] : 0;
|
||||||
if (random_value <= 0) {
|
if (random_value <= 0) {
|
||||||
chosen_value = k;
|
chosen_value = k;
|
||||||
break;
|
break;
|
||||||
@ -177,7 +177,7 @@ WaveFormCollapse::ObserveStatus WaveFormCollapse::observe() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// And define the cell with the pattern.
|
// And define the cell with the pattern.
|
||||||
for (int k = 0; k < patterns_frequencies.size(); k++) {
|
for (int k = 0; k < _patterns_frequencies.size(); k++) {
|
||||||
if (wave_get(argmin, k) != (k == chosen_value)) {
|
if (wave_get(argmin, k) != (k == chosen_value)) {
|
||||||
add_to_propagator(argmin / _wave_width, argmin % _wave_width, k);
|
add_to_propagator(argmin / _wave_width, argmin % _wave_width, k);
|
||||||
wave_set(argmin, k, false);
|
wave_set(argmin, k, false);
|
||||||
@ -191,7 +191,7 @@ Array2D<int> WaveFormCollapse::wave_to_output() const {
|
|||||||
Array2D<int> output_patterns(_wave_height, _wave_width);
|
Array2D<int> output_patterns(_wave_height, _wave_width);
|
||||||
|
|
||||||
for (int i = 0; i < _wave_size; i++) {
|
for (int i = 0; i < _wave_size; i++) {
|
||||||
for (int k = 0; k < patterns_frequencies.size(); k++) {
|
for (int k = 0; k < _patterns_frequencies.size(); k++) {
|
||||||
if (wave_get(i, k)) {
|
if (wave_get(i, k)) {
|
||||||
output_patterns.data.write[i] = k;
|
output_patterns.data.write[i] = k;
|
||||||
}
|
}
|
||||||
@ -202,7 +202,7 @@ Array2D<int> WaveFormCollapse::wave_to_output() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void WaveFormCollapse::wave_set(int index, int pattern, bool value) {
|
void WaveFormCollapse::wave_set(int index, int pattern, bool value) {
|
||||||
bool old_value = wave_data.get(index, pattern);
|
bool old_value = _wave_data.get(index, pattern);
|
||||||
|
|
||||||
// If the value isn't changed, nothing needs to be done.
|
// If the value isn't changed, nothing needs to be done.
|
||||||
if (old_value == value) {
|
if (old_value == value) {
|
||||||
@ -210,22 +210,22 @@ void WaveFormCollapse::wave_set(int index, int pattern, bool value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, the memoisation should be updated.
|
// Otherwise, the memoisation should be updated.
|
||||||
wave_data.get(index, pattern) = value;
|
_wave_data.get(index, pattern) = value;
|
||||||
|
|
||||||
memoisation_plogp_sum.write[index] -= plogp_patterns_frequencies[pattern];
|
_memoisation_plogp_sum.write[index] -= _plogp_patterns_frequencies[pattern];
|
||||||
memoisation_sum.write[index] -= patterns_frequencies[pattern];
|
_memoisation_sum.write[index] -= _patterns_frequencies[pattern];
|
||||||
memoisation_log_sum.write[index] = Math::log(memoisation_sum[index]);
|
_memoisation_log_sum.write[index] = Math::log(_memoisation_sum[index]);
|
||||||
memoisation_nb_patterns.write[index]--;
|
_memoisation_nb_patterns.write[index]--;
|
||||||
memoisation_entropy.write[index] = memoisation_log_sum[index] - memoisation_plogp_sum[index] / memoisation_sum[index];
|
_memoisation_entropy.write[index] = _memoisation_log_sum[index] - _memoisation_plogp_sum[index] / _memoisation_sum[index];
|
||||||
|
|
||||||
// If there is no patterns possible in the cell, then there is a contradiction.
|
// If there is no patterns possible in the cell, then there is a contradiction.
|
||||||
if (memoisation_nb_patterns[index] == 0) {
|
if (_memoisation_nb_patterns[index] == 0) {
|
||||||
is_impossible = true;
|
_is_impossible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WaveFormCollapse::wave_get_min_entropy() const {
|
int WaveFormCollapse::wave_get_min_entropy() const {
|
||||||
if (is_impossible) {
|
if (_is_impossible) {
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,14 +238,14 @@ int WaveFormCollapse::wave_get_min_entropy() const {
|
|||||||
|
|
||||||
for (int i = 0; i < _wave_size; i++) {
|
for (int i = 0; i < _wave_size; i++) {
|
||||||
// If the cell is decided, we do not compute the entropy (which is equal to 0).
|
// If the cell is decided, we do not compute the entropy (which is equal to 0).
|
||||||
int nb_patterns_local = memoisation_nb_patterns[i];
|
int nb_patterns_local = _memoisation_nb_patterns[i];
|
||||||
|
|
||||||
if (nb_patterns_local == 1) {
|
if (nb_patterns_local == 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, we take the memoised entropy.
|
// Otherwise, we take the memoised entropy.
|
||||||
double entropy = memoisation_entropy[i];
|
double entropy = _memoisation_entropy[i];
|
||||||
|
|
||||||
// We first check if the entropy is less than the minimum.
|
// We first check if the entropy is less than the minimum.
|
||||||
// This is important to reduce noise computation (which is not
|
// This is important to reduce noise computation (which is not
|
||||||
@ -254,7 +254,7 @@ int WaveFormCollapse::wave_get_min_entropy() const {
|
|||||||
// Then, we add noise to decide randomly which will be chosen.
|
// Then, we add noise to decide randomly which will be chosen.
|
||||||
// noise is smaller than the smallest p * log(p), so the minimum entropy
|
// noise is smaller than the smallest p * log(p), so the minimum entropy
|
||||||
// will always be chosen.
|
// will always be chosen.
|
||||||
double noise = pcg.random(0.0, min_abs_half_plogp);
|
double noise = pcg.random(0.0, _min_abs_half_plogp);
|
||||||
if (entropy + noise < min) {
|
if (entropy + noise < min) {
|
||||||
min = entropy + noise;
|
min = entropy + noise;
|
||||||
argmin = i;
|
argmin = i;
|
||||||
@ -269,11 +269,11 @@ void WaveFormCollapse::init_compatible() {
|
|||||||
// We compute the number of pattern compatible in all directions.
|
// We compute the number of pattern compatible in all directions.
|
||||||
for (int y = 0; y < _wave_height; y++) {
|
for (int y = 0; y < _wave_height; y++) {
|
||||||
for (int x = 0; x < _wave_width; x++) {
|
for (int x = 0; x < _wave_width; x++) {
|
||||||
for (int pattern = 0; pattern < propagator_state.size(); pattern++) {
|
for (int pattern = 0; pattern < _propagator_state.size(); pattern++) {
|
||||||
CompatibilityEntry &value = compatible.get(y, x, pattern);
|
CompatibilityEntry &value = _compatible.get(y, x, pattern);
|
||||||
|
|
||||||
for (int direction = 0; direction < 4; direction++) {
|
for (int direction = 0; direction < 4; direction++) {
|
||||||
value.direction[direction] = propagator_state[pattern].directions[get_opposite_direction(direction)].size();
|
value.direction[direction] = _propagator_state[pattern].directions[get_opposite_direction(direction)].size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,16 +282,16 @@ void WaveFormCollapse::init_compatible() {
|
|||||||
|
|
||||||
void WaveFormCollapse::propagate() {
|
void WaveFormCollapse::propagate() {
|
||||||
// We propagate every element while there is element to propagate.
|
// We propagate every element while there is element to propagate.
|
||||||
while (propagating.size() != 0) {
|
while (_propagating.size() != 0) {
|
||||||
// The cell and pattern that has been set to false.
|
// The cell and pattern that has been set to false.
|
||||||
|
|
||||||
const PropagatingEntry &e = propagating[propagating.size() - 1];
|
const PropagatingEntry &e = _propagating[_propagating.size() - 1];
|
||||||
|
|
||||||
int y1 = e.data[0];
|
int y1 = e.data[0];
|
||||||
int x1 = e.data[1];
|
int x1 = e.data[1];
|
||||||
int pattern = e.data[2];
|
int pattern = e.data[2];
|
||||||
|
|
||||||
propagating.resize(propagating.size() - 1);
|
_propagating.resize(_propagating.size() - 1);
|
||||||
|
|
||||||
// We propagate the information in all 4 directions.
|
// We propagate the information in all 4 directions.
|
||||||
for (int direction = 0; direction < 4; direction++) {
|
for (int direction = 0; direction < 4; direction++) {
|
||||||
@ -300,7 +300,7 @@ void WaveFormCollapse::propagate() {
|
|||||||
int dy = DIRECTIONS_Y[direction];
|
int dy = DIRECTIONS_Y[direction];
|
||||||
int x2, y2;
|
int x2, y2;
|
||||||
|
|
||||||
if (periodic_output) {
|
if (_periodic_output) {
|
||||||
x2 = ((int)x1 + dx + _wave_width) % _wave_width;
|
x2 = ((int)x1 + dx + _wave_width) % _wave_width;
|
||||||
y2 = ((int)y1 + dy + _wave_height) % _wave_height;
|
y2 = ((int)y1 + dy + _wave_height) % _wave_height;
|
||||||
} else {
|
} else {
|
||||||
@ -318,7 +318,7 @@ void WaveFormCollapse::propagate() {
|
|||||||
|
|
||||||
// The index of the second cell, and the patterns compatible
|
// The index of the second cell, and the patterns compatible
|
||||||
int i2 = x2 + y2 * _wave_width;
|
int i2 = x2 + y2 * _wave_width;
|
||||||
const Vector<int> &patterns = propagator_state[pattern].directions[direction];
|
const Vector<int> &patterns = _propagator_state[pattern].directions[direction];
|
||||||
|
|
||||||
// For every pattern that could be placed in that cell without being in
|
// For every pattern that could be placed in that cell without being in
|
||||||
// contradiction with pattern1
|
// contradiction with pattern1
|
||||||
@ -329,7 +329,7 @@ void WaveFormCollapse::propagate() {
|
|||||||
// We decrease the number of compatible patterns in the opposite
|
// We decrease the number of compatible patterns in the opposite
|
||||||
// direction If the pattern was discarded from the wave, the element
|
// direction If the pattern was discarded from the wave, the element
|
||||||
// is still negative, which is not a problem
|
// is still negative, which is not a problem
|
||||||
CompatibilityEntry &value = compatible.get(y2, x2, pattern_entry);
|
CompatibilityEntry &value = _compatible.get(y2, x2, pattern_entry);
|
||||||
value.direction[direction]--;
|
value.direction[direction]--;
|
||||||
|
|
||||||
// If the element was set to 0 with this operation, we need to remove
|
// If the element was set to 0 with this operation, we need to remove
|
||||||
@ -347,57 +347,57 @@ void WaveFormCollapse::initialize() {
|
|||||||
//wave
|
//wave
|
||||||
init_wave();
|
init_wave();
|
||||||
|
|
||||||
plogp_patterns_frequencies = get_plogp(patterns_frequencies);
|
_plogp_patterns_frequencies = get_plogp(_patterns_frequencies);
|
||||||
min_abs_half_plogp = get_min_abs_half(plogp_patterns_frequencies);
|
_min_abs_half_plogp = get_min_abs_half(_plogp_patterns_frequencies);
|
||||||
|
|
||||||
is_impossible = false;
|
_is_impossible = false;
|
||||||
nb_patterns = patterns_frequencies.size();
|
_nb_patterns = _patterns_frequencies.size();
|
||||||
|
|
||||||
wave_data.resize_fill(_wave_size, nb_patterns, true);
|
_wave_data.resize_fill(_wave_size, _nb_patterns, true);
|
||||||
|
|
||||||
// Initialize the memoisation of entropy.
|
// Initialize the memoisation of entropy.
|
||||||
double base_entropy = 0;
|
double base_entropy = 0;
|
||||||
double base_s = 0;
|
double base_s = 0;
|
||||||
|
|
||||||
for (int i = 0; i < patterns_frequencies.size(); i++) {
|
for (int i = 0; i < _patterns_frequencies.size(); i++) {
|
||||||
base_entropy += plogp_patterns_frequencies[i];
|
base_entropy += _plogp_patterns_frequencies[i];
|
||||||
base_s += patterns_frequencies[i];
|
base_s += _patterns_frequencies[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
double log_base_s = Math::log(base_s);
|
double log_base_s = Math::log(base_s);
|
||||||
double entropy_base = log_base_s - base_entropy / base_s;
|
double entropy_base = log_base_s - base_entropy / base_s;
|
||||||
|
|
||||||
memoisation_plogp_sum.resize(_wave_size);
|
_memoisation_plogp_sum.resize(_wave_size);
|
||||||
memoisation_plogp_sum.fill(base_entropy);
|
_memoisation_plogp_sum.fill(base_entropy);
|
||||||
|
|
||||||
memoisation_sum.resize(_wave_size);
|
_memoisation_sum.resize(_wave_size);
|
||||||
memoisation_sum.fill(base_s);
|
_memoisation_sum.fill(base_s);
|
||||||
|
|
||||||
memoisation_log_sum.resize(_wave_size);
|
_memoisation_log_sum.resize(_wave_size);
|
||||||
memoisation_log_sum.fill(log_base_s);
|
_memoisation_log_sum.fill(log_base_s);
|
||||||
|
|
||||||
memoisation_nb_patterns.resize(_wave_size);
|
_memoisation_nb_patterns.resize(_wave_size);
|
||||||
memoisation_nb_patterns.fill(patterns_frequencies.size());
|
_memoisation_nb_patterns.fill(_patterns_frequencies.size());
|
||||||
|
|
||||||
memoisation_entropy.resize(_wave_size);
|
_memoisation_entropy.resize(_wave_size);
|
||||||
memoisation_entropy.fill(entropy_base);
|
_memoisation_entropy.fill(entropy_base);
|
||||||
|
|
||||||
//propagator
|
//propagator
|
||||||
compatible.resize(_wave_height, _wave_width, propagator_state.size());
|
_compatible.resize(_wave_height, _wave_width, _propagator_state.size());
|
||||||
init_compatible();
|
init_compatible();
|
||||||
}
|
}
|
||||||
|
|
||||||
WaveFormCollapse::WaveFormCollapse() {
|
WaveFormCollapse::WaveFormCollapse() {
|
||||||
periodic_output = true;
|
_periodic_output = true;
|
||||||
is_impossible = false;
|
_is_impossible = false;
|
||||||
|
|
||||||
nb_patterns = 0;
|
_nb_patterns = 0;
|
||||||
|
|
||||||
_wave_width = 0;
|
_wave_width = 0;
|
||||||
_wave_height = 0;
|
_wave_height = 0;
|
||||||
_wave_size = 0;
|
_wave_size = 0;
|
||||||
|
|
||||||
min_abs_half_plogp = 0;
|
_min_abs_half_plogp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
WaveFormCollapse::~WaveFormCollapse() {
|
WaveFormCollapse::~WaveFormCollapse() {
|
||||||
|
@ -97,7 +97,7 @@ public:
|
|||||||
|
|
||||||
// Return true if pattern can be placed in cell index.
|
// Return true if pattern can be placed in cell index.
|
||||||
bool wave_get(int index, int pattern) const {
|
bool wave_get(int index, int pattern) const {
|
||||||
return wave_data.get(index, pattern);
|
return _wave_data.get(index, pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if pattern can be placed in cell (i,j)
|
// Return true if pattern can be placed in cell (i,j)
|
||||||
@ -121,9 +121,9 @@ public:
|
|||||||
void add_to_propagator(int y, int x, int pattern) {
|
void add_to_propagator(int y, int x, int pattern) {
|
||||||
// All the direction are set to 0, since the pattern cannot be set in (y,x).
|
// All the direction are set to 0, since the pattern cannot be set in (y,x).
|
||||||
CompatibilityEntry temp;
|
CompatibilityEntry temp;
|
||||||
compatible.get(y, x, pattern) = temp;
|
_compatible.get(y, x, pattern) = temp;
|
||||||
|
|
||||||
propagating.push_back(PropagatingEntry(y, x, pattern));
|
_propagating.push_back(PropagatingEntry(y, x, pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr int get_opposite_direction(int direction) {
|
constexpr int get_opposite_direction(int direction) {
|
||||||
@ -144,9 +144,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
Array2D<int> input;
|
Array2D<int> _input;
|
||||||
|
|
||||||
bool periodic_output;
|
bool _periodic_output;
|
||||||
|
|
||||||
//Wave
|
//Wave
|
||||||
int _wave_width;
|
int _wave_width;
|
||||||
@ -154,10 +154,10 @@ protected:
|
|||||||
int _wave_size;
|
int _wave_size;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RandomPCG gen;
|
RandomPCG _gen;
|
||||||
|
|
||||||
// The number of distinct patterns.
|
// The number of distinct patterns.
|
||||||
size_t nb_patterns;
|
size_t _nb_patterns;
|
||||||
|
|
||||||
// Transform the wave to a valid output (a 2d array of patterns that aren't in
|
// Transform the wave to a valid output (a 2d array of patterns that aren't in
|
||||||
// contradiction). This function should be used only when all cell of the wave
|
// contradiction). This function should be used only when all cell of the wave
|
||||||
@ -165,40 +165,40 @@ private:
|
|||||||
Array2D<int> wave_to_output() const;
|
Array2D<int> wave_to_output() const;
|
||||||
|
|
||||||
// The patterns frequencies p given to wfc.
|
// The patterns frequencies p given to wfc.
|
||||||
Vector<double> patterns_frequencies;
|
Vector<double> _patterns_frequencies;
|
||||||
|
|
||||||
// The precomputation of p * log(p).
|
// The precomputation of p * log(p).
|
||||||
Vector<double> plogp_patterns_frequencies;
|
Vector<double> _plogp_patterns_frequencies;
|
||||||
|
|
||||||
// The precomputation of min (p * log(p)) / 2.
|
// The precomputation of min (p * log(p)) / 2.
|
||||||
// This is used to define the maximum value of the noise.
|
// This is used to define the maximum value of the noise.
|
||||||
double min_abs_half_plogp;
|
double _min_abs_half_plogp;
|
||||||
|
|
||||||
Vector<double> memoisation_plogp_sum; // The sum of p'(pattern)// log(p'(pattern)).
|
Vector<double> _memoisation_plogp_sum; // The sum of p'(pattern)// log(p'(pattern)).
|
||||||
Vector<double> memoisation_sum; // The sum of p'(pattern).
|
Vector<double> _memoisation_sum; // The sum of p'(pattern).
|
||||||
Vector<double> memoisation_log_sum; // The log of sum.
|
Vector<double> _memoisation_log_sum; // The log of sum.
|
||||||
Vector<int> memoisation_nb_patterns; // The number of patterns present
|
Vector<int> _memoisation_nb_patterns; // The number of patterns present
|
||||||
Vector<double> memoisation_entropy; // The entropy of the cell.
|
Vector<double> _memoisation_entropy; // The entropy of the cell.
|
||||||
|
|
||||||
// This value is set to true if there is a contradiction in the wave (all elements set to false in a cell).
|
// This value is set to true if there is a contradiction in the wave (all elements set to false in a cell).
|
||||||
bool is_impossible;
|
bool _is_impossible;
|
||||||
|
|
||||||
// The actual wave. wave_data.get(index, pattern) is equal to false if the pattern can be placed in the cell index.
|
// The actual wave. wave_data.get(index, pattern) is equal to false if the pattern can be placed in the cell index.
|
||||||
Array2D<bool> wave_data;
|
Array2D<bool> _wave_data;
|
||||||
|
|
||||||
//Propagator
|
//Propagator
|
||||||
Vector<PropagatorStateEntry> propagator_state;
|
Vector<PropagatorStateEntry> _propagator_state;
|
||||||
|
|
||||||
// All the tuples (y, x, pattern) that should be propagated.
|
// All the tuples (y, x, pattern) that should be propagated.
|
||||||
// The tuple should be propagated when wave.get(y, x, pattern) is set to false.
|
// The tuple should be propagated when wave.get(y, x, pattern) is set to false.
|
||||||
Vector<PropagatingEntry> propagating;
|
Vector<PropagatingEntry> _propagating;
|
||||||
|
|
||||||
// compatible.get(y, x, pattern)[direction] contains the number of patterns
|
// 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
|
// 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
|
// 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
|
// 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
|
// compatible.get(y, x, pattern) has every element negative or null
|
||||||
Array3D<CompatibilityEntry> compatible;
|
Array3D<CompatibilityEntry> _compatible;
|
||||||
|
|
||||||
void init_compatible();
|
void init_compatible();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user