mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-11 13:21: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 int &seed,
|
||||
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()) {
|
||||
// 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<std::array<Vector<uint32_t>, 4>> generate_compatible(const Vector<Array2D<T>> &patterns) {
|
||||
Vector<std::array<Vector<uint32_t>, 4>> compatible = Vector<std::array<Vector<uint32_t>, 4>>(patterns.size());
|
||||
static Vector<PropagatorEntry> generate_compatible(const Vector<Array2D<T>> &patterns) {
|
||||
Vector<PropagatorEntry> compatible = Vector<PropagatorEntry>(patterns.size());
|
||||
|
||||
// Iterate on every dy, dx, pattern1 and pattern2
|
||||
for (uint32_t pattern1 = 0; pattern1 < patterns.size(); pattern1++) {
|
||||
|
@ -2,13 +2,14 @@
|
||||
#include "wave.h"
|
||||
|
||||
void Propagator::init_compatible() {
|
||||
std::array<int, 4> 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<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;
|
||||
@ -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<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
|
||||
// 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<int, 4> &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);
|
||||
}
|
||||
|
@ -2,16 +2,19 @@
|
||||
#define FAST_WFC_PROPAGATOR_HPP_
|
||||
|
||||
#include "array_3d.h"
|
||||
#include "direction.h"
|
||||
#include <array>
|
||||
#include <tuple>
|
||||
#include "core/vector.h"
|
||||
#include "direction.h"
|
||||
#include <tuple>
|
||||
|
||||
class Wave;
|
||||
|
||||
class Propagator {
|
||||
public:
|
||||
using PropagatorState = Vector<std::array<Vector<uint32_t>, 4>>;
|
||||
struct PropagatorEntry {
|
||||
Vector<uint32_t> directions[4];
|
||||
};
|
||||
|
||||
using PropagatorState = Vector<PropagatorEntry>;
|
||||
|
||||
private:
|
||||
const uint32_t patterns_size;
|
||||
@ -28,12 +31,22 @@ private:
|
||||
// false.
|
||||
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
|
||||
// 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<std::array<int, 4>> compatible;
|
||||
Array3D<CompatibilityEntry> 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<int, 4> temp = {};
|
||||
CompatibilityEntry temp;
|
||||
compatible.get(y, x, pattern) = temp;
|
||||
|
||||
|
||||
propagating.push_back(std::tuple<uint32_t, uint32_t, uint32_t>(y, x, pattern));
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef FAST_WFC_TILING_WFC_HPP_
|
||||
#define FAST_WFC_TILING_WFC_HPP_
|
||||
|
||||
#include <unordered_map>
|
||||
#include "core/vector.h"
|
||||
#include <unordered_map>
|
||||
|
||||
#include "array_2d.h"
|
||||
#include "wfc.h"
|
||||
@ -199,16 +199,30 @@ private:
|
||||
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.
|
||||
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,
|
||||
Vector<Tile<T>> tiles,
|
||||
Vector<std::pair<uint32_t, uint32_t>> id_to_oriented_tile,
|
||||
Vector<Vector<uint32_t>> oriented_tile_ids) {
|
||||
|
||||
|
||||
size_t nb_oriented_tiles = id_to_oriented_tile.size();
|
||||
Vector<std::array<Vector<bool>, 4>> 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) });
|
||||
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) });
|
||||
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<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 j = 0; j < nb_oriented_tiles; ++j) {
|
||||
|
Loading…
Reference in New Issue
Block a user