133 lines
5.0 KiB
C++
133 lines
5.0 KiB
C++
#include "zeroerr/assert.h"
|
|
#include "zeroerr/unittest.h"
|
|
|
|
#include "procgen/core/ProcgenCore.h"
|
|
|
|
#include <string>
|
|
#include <type_traits>
|
|
|
|
namespace {
|
|
|
|
static_assert(std::is_default_constructible_v<eve::procgen::Params>);
|
|
static_assert(std::is_default_constructible_v<eve::procgen::Grid2D>);
|
|
static_assert(std::is_default_constructible_v<eve::procgen::PointSet>);
|
|
static_assert(std::is_default_constructible_v<eve::procgen::MeshBuild>);
|
|
|
|
} // namespace
|
|
|
|
TEST_CASE("procgen.core.cpuSurfaceIsBackendNeutral") {
|
|
using namespace eve::procgen;
|
|
|
|
Params params;
|
|
params.setSeed(42);
|
|
params.setSize(4, 3);
|
|
params.setBool("decorations", true);
|
|
|
|
const RecipeDescriptor recipe = RecipeDescriptor::grid("core.grid", "Core Grid", "test", 1, 1, 32, 32);
|
|
recipe.applyDefaults(params);
|
|
CHECK_EQ(params.getSeed(), uint32_t(42));
|
|
CHECK_EQ(params.getWidth(), 4);
|
|
CHECK_EQ(params.getHeight(), 3);
|
|
|
|
Grid2D grid;
|
|
grid.resize(params.getWidth(), params.getHeight());
|
|
grid.fill(int(Semantic::Floor));
|
|
grid.setMeta("buildKey", "core-grid:v1:42:4x3");
|
|
CHECK_EQ(grid.getCell(2, 1), int(Semantic::Floor));
|
|
CHECK_EQ(grid.getMeta("buildKey", ""), std::string("core-grid:v1:42:4x3"));
|
|
|
|
PointSet points;
|
|
points.add(1.f, 0.f, 2.f);
|
|
const PointSet jittered = jitterPointPositions(points, params.getSeed(), 0.25f, 0.25f);
|
|
CHECK_EQ(jittered.getCount(), 1);
|
|
CHECK_EQ(deriveSeed(params.getSeed(), "terrain"), deriveSeed(params.getSeed(), "terrain"));
|
|
CHECK(deriveSeed(params.getSeed(), "terrain") != deriveSeed(params.getSeed(), "props"));
|
|
|
|
MeshBuild mesh;
|
|
mesh.addVertex(0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f);
|
|
mesh.addVertex(1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 1.f, 0.f);
|
|
mesh.addVertex(0.f, 0.f, 1.f, 0.f, 1.f, 0.f, 0.f, 1.f);
|
|
mesh.addTriangle(0, 1, 2);
|
|
CHECK_EQ(mesh.getVertexCount(), 3);
|
|
CHECK_EQ(mesh.getIndexCount(), 3);
|
|
|
|
ProcgenContext context("core-system", params.getSeed(), "core-grid:v1:42:4x3");
|
|
CHECK_EQ(context.getBuildKey(), std::string("core-grid:v1:42:4x3"));
|
|
CHECK_EQ(context.seedFor("terrain"), deriveSeed(params.getSeed(), "terrain"));
|
|
}
|
|
|
|
TEST_CASE("procgen.params.typedStorageConversionsAndCanonicalEncoding") {
|
|
using namespace eve::procgen;
|
|
|
|
Params params;
|
|
params.setInt("count", 7);
|
|
params.setFloat("ratio", 1.5f);
|
|
params.setBool("enabled", true);
|
|
params.setString("label", "7");
|
|
|
|
// Numeric conversion is explicit and does not go through text.
|
|
CHECK_EQ(params.getInt("count", -1), 7);
|
|
CHECK_EQ(params.getFloat("count", -1.f), 7.f);
|
|
CHECK_EQ(params.getFloat("ratio", -1.f), 1.5f);
|
|
CHECK_EQ(params.getInt("ratio", -1), -1); // fractional Double is not truncated
|
|
CHECK(params.getBool("enabled", false));
|
|
CHECK_EQ(params.getInt("enabled", -1), 1); // Bool has only 0/1 numeric conversion
|
|
CHECK_EQ(params.getString("count", "wrong-kind"), "wrong-kind");
|
|
CHECK_EQ(params.getInt("label", -1), -1); // String is never parsed
|
|
CHECK(params.getBool("label", true)); // invalid kind returns the caller default
|
|
|
|
const std::string canonical = params.canonicalString();
|
|
CHECK(canonical.find("int:7") != std::string::npos);
|
|
CHECK(canonical.find("double:") != std::string::npos);
|
|
CHECK(canonical.find("bool:1") != std::string::npos);
|
|
CHECK(canonical.find("string:1:7") != std::string::npos);
|
|
|
|
Params sameValues;
|
|
sameValues.setString("label", "7");
|
|
sameValues.setBool("enabled", true);
|
|
sameValues.setFloat("ratio", 1.5f);
|
|
sameValues.setInt("count", 7);
|
|
CHECK_EQ(sameValues.canonicalString(), canonical);
|
|
|
|
Params differentKind;
|
|
differentKind.setInt("count", 7);
|
|
differentKind.setFloat("ratio", 1.5f);
|
|
differentKind.setBool("enabled", true);
|
|
differentKind.setInt("label", 7);
|
|
CHECK(differentKind.canonicalString() != canonical);
|
|
}
|
|
|
|
TEST_CASE("procgen.params.dimensionsHaveDedicatedSemantics") {
|
|
using namespace eve::procgen;
|
|
|
|
Params params;
|
|
params.setSize(0, -4);
|
|
CHECK_EQ(params.getWidth(), 1);
|
|
CHECK_EQ(params.getHeight(), 1);
|
|
params.setInt("width", 64);
|
|
params.setInt("height", 48);
|
|
params.setInt("seed", 123);
|
|
CHECK_EQ(params.getWidth(), 64);
|
|
CHECK_EQ(params.getHeight(), 48);
|
|
CHECK_EQ(params.getSeed(), uint32_t(123));
|
|
CHECK_EQ(params.getInt("width", -1), 64);
|
|
CHECK_EQ(params.getInt("height", -1), 48);
|
|
CHECK_EQ(params.getInt("seed", -1), 123);
|
|
|
|
// Mesh recipes also use width/height as floating algorithm parameters;
|
|
// those values remain separate from the grid dimensions.
|
|
params.setFloat("width", 2.5f);
|
|
params.setString("height", "building-height");
|
|
CHECK_EQ(params.getWidth(), 64);
|
|
CHECK_EQ(params.getHeight(), 48);
|
|
CHECK_EQ(params.getFloat("width", -1.f), 2.5f);
|
|
CHECK_EQ(params.getString("height", "missing"), "building-height");
|
|
|
|
Params reordered;
|
|
reordered.setString("height", "building-height");
|
|
reordered.setFloat("width", 2.5f);
|
|
reordered.setSeed(123);
|
|
reordered.setSize(64, 48);
|
|
CHECK_EQ(reordered.canonicalString(), params.canonicalString());
|
|
}
|