mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-11 21:31:10 +01:00
Got rid of std::arrays in the wfc module.
This commit is contained in:
parent
e4a2429b45
commit
bb723e3c44
@ -43,7 +43,7 @@ private:
|
|||||||
const Array2D<T> &input, const OverlappingWFCOptions &options,
|
const Array2D<T> &input, const OverlappingWFCOptions &options,
|
||||||
const int &seed,
|
const int &seed,
|
||||||
const std::pair<Vector<Array2D<T>>, Vector<double>> &patterns,
|
const std::pair<Vector<Array2D<T>>, Vector<double>> &patterns,
|
||||||
const Vector<std::array<Vector<uint32_t>, 4>> &propagator) :
|
const Vector<PropagatorEntry> &propagator) :
|
||||||
input(input), options(options), patterns(patterns.first), wfc(options.periodic_output, seed, patterns.second, propagator, options.get_wave_height(), options.get_wave_width()) {
|
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 necessary, the ground is set.
|
||||||
if (options.ground) {
|
if (options.ground) {
|
||||||
@ -156,8 +156,8 @@ private:
|
|||||||
// If agrees(pattern1, pattern2, dy, dx), then compatible[pattern1][direction]
|
// If agrees(pattern1, pattern2, dy, dx), then compatible[pattern1][direction]
|
||||||
// contains pattern2, where direction is the direction defined by (dy, dx)
|
// contains pattern2, where direction is the direction defined by (dy, dx)
|
||||||
// (see direction.hpp).
|
// (see direction.hpp).
|
||||||
static Vector<std::array<Vector<uint32_t>, 4>> generate_compatible(const Vector<Array2D<T>> &patterns) {
|
static Vector<PropagatorEntry> generate_compatible(const Vector<Array2D<T>> &patterns) {
|
||||||
Vector<std::array<Vector<uint32_t>, 4>> compatible = Vector<std::array<Vector<uint32_t>, 4>>(patterns.size());
|
Vector<PropagatorEntry> compatible = Vector<PropagatorEntry>(patterns.size());
|
||||||
|
|
||||||
// Iterate on every dy, dx, pattern1 and pattern2
|
// Iterate on every dy, dx, pattern1 and pattern2
|
||||||
for (uint32_t pattern1 = 0; pattern1 < patterns.size(); pattern1++) {
|
for (uint32_t pattern1 = 0; pattern1 < patterns.size(); pattern1++) {
|
||||||
|
@ -2,13 +2,14 @@
|
|||||||
#include "wave.h"
|
#include "wave.h"
|
||||||
|
|
||||||
void Propagator::init_compatible() {
|
void Propagator::init_compatible() {
|
||||||
std::array<int, 4> value;
|
CompatibilityEntry value;
|
||||||
// We compute the number of pattern compatible in all directions.
|
// We compute the number of pattern compatible in all directions.
|
||||||
for (uint32_t y = 0; y < wave_height; y++) {
|
for (uint32_t y = 0; y < wave_height; y++) {
|
||||||
for (uint32_t x = 0; x < wave_width; x++) {
|
for (uint32_t x = 0; x < wave_width; x++) {
|
||||||
for (uint32_t pattern = 0; pattern < patterns_size; pattern++) {
|
for (uint32_t pattern = 0; pattern < patterns_size; pattern++) {
|
||||||
|
|
||||||
for (int direction = 0; direction < 4; direction++) {
|
for (int direction = 0; direction < 4; direction++) {
|
||||||
value[direction] = static_cast<uint32_t>(propagator_state[pattern][get_opposite_direction(direction)].size());
|
value.direction[direction] = static_cast<uint32_t>(propagator_state[pattern].directions[get_opposite_direction(direction)].size());
|
||||||
}
|
}
|
||||||
|
|
||||||
compatible.get(y, x, pattern) = value;
|
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
|
// The index of the second cell, and the patterns compatible
|
||||||
uint32_t i2 = x2 + y2 * wave.width;
|
uint32_t i2 = x2 + y2 * wave.width;
|
||||||
const Vector<uint32_t> &patterns = propagator_state[pattern][direction];
|
const Vector<uint32_t> &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
|
||||||
@ -58,12 +59,12 @@ void Propagator::propagate(Wave &wave) {
|
|||||||
// 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
|
||||||
std::array<int, 4> &value = compatible.get(y2, x2, pattern);
|
CompatibilityEntry &value = compatible.get(y2, x2, pattern);
|
||||||
value[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
|
||||||
// the pattern from the wave, and propagate the information
|
// the pattern from the wave, and propagate the information
|
||||||
if (value[direction] == 0) {
|
if (value.direction[direction] == 0) {
|
||||||
add_to_propagator(y2, x2, pattern);
|
add_to_propagator(y2, x2, pattern);
|
||||||
wave.set(i2, pattern, false);
|
wave.set(i2, pattern, false);
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,19 @@
|
|||||||
#define FAST_WFC_PROPAGATOR_HPP_
|
#define FAST_WFC_PROPAGATOR_HPP_
|
||||||
|
|
||||||
#include "array_3d.h"
|
#include "array_3d.h"
|
||||||
#include "direction.h"
|
|
||||||
#include <array>
|
|
||||||
#include <tuple>
|
|
||||||
#include "core/vector.h"
|
#include "core/vector.h"
|
||||||
|
#include "direction.h"
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
class Wave;
|
class Wave;
|
||||||
|
|
||||||
class Propagator {
|
class Propagator {
|
||||||
public:
|
public:
|
||||||
using PropagatorState = Vector<std::array<Vector<uint32_t>, 4>>;
|
struct PropagatorEntry {
|
||||||
|
Vector<uint32_t> directions[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
using PropagatorState = Vector<PropagatorEntry>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint32_t patterns_size;
|
const uint32_t patterns_size;
|
||||||
@ -28,12 +31,22 @@ private:
|
|||||||
// false.
|
// false.
|
||||||
Vector<std::tuple<uint32_t, uint32_t, uint32_t>> propagating;
|
Vector<std::tuple<uint32_t, uint32_t, uint32_t>> 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
|
// 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<std::array<int, 4>> compatible;
|
Array3D<CompatibilityEntry> compatible;
|
||||||
|
|
||||||
void init_compatible();
|
void init_compatible();
|
||||||
|
|
||||||
@ -51,9 +64,9 @@ public:
|
|||||||
|
|
||||||
void add_to_propagator(uint32_t y, uint32_t x, uint32_t pattern) {
|
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).
|
// All the direction are set to 0, since the pattern cannot be set in (y,x).
|
||||||
std::array<int, 4> temp = {};
|
CompatibilityEntry temp;
|
||||||
compatible.get(y, x, pattern) = temp;
|
compatible.get(y, x, pattern) = temp;
|
||||||
|
|
||||||
propagating.push_back(std::tuple<uint32_t, uint32_t, uint32_t>(y, x, pattern));
|
propagating.push_back(std::tuple<uint32_t, uint32_t, uint32_t>(y, x, pattern));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#ifndef FAST_WFC_TILING_WFC_HPP_
|
#ifndef FAST_WFC_TILING_WFC_HPP_
|
||||||
#define FAST_WFC_TILING_WFC_HPP_
|
#define FAST_WFC_TILING_WFC_HPP_
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
#include "core/vector.h"
|
#include "core/vector.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
#include "array_2d.h"
|
#include "array_2d.h"
|
||||||
#include "wfc.h"
|
#include "wfc.h"
|
||||||
@ -199,16 +199,30 @@ private:
|
|||||||
return { id_to_oriented_tile, oriented_tile_ids };
|
return { id_to_oriented_tile, oriented_tile_ids };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct DensePropagatorHelper {
|
||||||
|
Vector<bool> 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.
|
// Generate the propagator which will be used in the wfc algorithm.
|
||||||
static Vector<std::array<Vector<uint32_t>, 4>> generate_propagator(
|
static Vector<PropagatorEntry> generate_propagator(
|
||||||
const Vector<std::tuple<uint32_t, uint32_t, uint32_t, uint32_t>> &neighbors,
|
const Vector<std::tuple<uint32_t, uint32_t, uint32_t, uint32_t>> &neighbors,
|
||||||
Vector<Tile<T>> tiles,
|
Vector<Tile<T>> tiles,
|
||||||
Vector<std::pair<uint32_t, uint32_t>> id_to_oriented_tile,
|
Vector<std::pair<uint32_t, uint32_t>> id_to_oriented_tile,
|
||||||
Vector<Vector<uint32_t>> oriented_tile_ids) {
|
Vector<Vector<uint32_t>> oriented_tile_ids) {
|
||||||
|
|
||||||
size_t nb_oriented_tiles = id_to_oriented_tile.size();
|
size_t nb_oriented_tiles = id_to_oriented_tile.size();
|
||||||
Vector<std::array<Vector<bool>, 4>> dense_propagator(
|
Vector<DensePropagatorHelper> dense_propagator(nb_oriented_tiles, { Vector<bool>(nb_oriented_tiles, false), Vector<bool>(nb_oriented_tiles, false), Vector<bool>(nb_oriented_tiles, false), Vector<bool>(nb_oriented_tiles, false) });
|
||||||
nb_oriented_tiles, { Vector<bool>(nb_oriented_tiles, false), Vector<bool>(nb_oriented_tiles, false), Vector<bool>(nb_oriented_tiles, false), Vector<bool>(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) {
|
for (auto neighbor : neighbors) {
|
||||||
uint32_t tile1 = std::get<0>(neighbor);
|
uint32_t tile1 = std::get<0>(neighbor);
|
||||||
@ -240,7 +254,7 @@ private:
|
|||||||
add(7, 0);
|
add(7, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<std::array<Vector<uint32_t>, 4>> propagator(nb_oriented_tiles);
|
Vector<PropagatorEntry> propagator(nb_oriented_tiles);
|
||||||
|
|
||||||
for (size_t i = 0; i < nb_oriented_tiles; ++i) {
|
for (size_t i = 0; i < nb_oriented_tiles; ++i) {
|
||||||
for (size_t j = 0; j < nb_oriented_tiles; ++j) {
|
for (size_t j = 0; j < nb_oriented_tiles; ++j) {
|
||||||
|
Loading…
Reference in New Issue
Block a user