test: extend coverage of testTileTexture
This commit is contained in:
1 parent
ea0e3b2ad0
commit
522662ded6
1 file changed
+140
@@ -301,3 +301,143 @@ VF_TEST(writeTileAgreesWithPixelAtEverywhere) {
|
||||
}
|
||||
}
|
||||
|
||||
// The atlas is built at sixteen pixels today, but nothing in the palette is
|
||||
// allowed to depend on that. Alpha rules and contrast have to survive a
|
||||
// different tile size.
|
||||
VF_TEST(tilesKeepTheirAlphaAndContrastAtOtherTileSizes) {
|
||||
const int sizes[] = {8, 16, 32};
|
||||
for (int size : sizes) {
|
||||
TileTextureParams params;
|
||||
params.tileSize = size;
|
||||
TileSampler sampler(params);
|
||||
for (int tile = 0; tile < renderedTiles(sampler); ++tile) {
|
||||
const TileSpec& spec = sampler.palette().specFor(tile);
|
||||
int holes = 0;
|
||||
int solid = 0;
|
||||
for (int y = 0; y < size; ++y) {
|
||||
for (int x = 0; x < size; ++x) {
|
||||
uint8_t alpha = sampler.pixelAt(tile, x, y).a;
|
||||
if (alpha == 0) ++holes;
|
||||
if (alpha == 255) ++solid;
|
||||
}
|
||||
}
|
||||
CHECK_EQ(holes + solid, size * size);
|
||||
if (spec.cutout) {
|
||||
CHECK(holes > 0);
|
||||
CHECK(solid > 0);
|
||||
if (holes == 0 || solid == 0) {
|
||||
std::printf(" tile %d (%s) at size %d: %d holes, %d solid\n", tile, spec.name,
|
||||
size, holes, solid);
|
||||
}
|
||||
} else {
|
||||
CHECK_EQ(holes, 0);
|
||||
}
|
||||
int spread = interiorRange(sampler, tile).spread();
|
||||
CHECK(spread >= 8);
|
||||
if (spread < 8) {
|
||||
std::printf(" tile %d (%s) at size %d is flat: spread %d\n", tile, spec.name, size,
|
||||
spread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Boards run one way and their grain runs with them. Flipping the spec's axis
|
||||
// has to flip which direction the tile varies in, otherwise the plank pattern
|
||||
// is drawing wallpaper.
|
||||
VF_TEST(plankGrainFollowsTheBoardDirection) {
|
||||
TileSampler sampler;
|
||||
int size = sampler.params().tileSize;
|
||||
|
||||
TileSpec board;
|
||||
board.name = "testBoard";
|
||||
board.pattern = TilePattern::Plank;
|
||||
board.material = TileMaterial::Wood;
|
||||
board.base = TileRgb{160, 120, 70};
|
||||
board.accent = TileRgb{90, 64, 34};
|
||||
board.noise = 0.0f;
|
||||
board.scale = 0.35f;
|
||||
board.density = 0.50f;
|
||||
|
||||
TileSpec upright = board;
|
||||
upright.vertical = true;
|
||||
|
||||
auto axisSpread = [&](const TileSpec& spec, bool alongColumns) {
|
||||
int lowest = 255;
|
||||
int highest = 0;
|
||||
for (int outer = 1; outer < size; ++outer) {
|
||||
int total = 0;
|
||||
for (int inner = 1; inner < size; ++inner) {
|
||||
int x = alongColumns ? outer : inner;
|
||||
int y = alongColumns ? inner : outer;
|
||||
total += luminance(sampler.pixelOf(spec, 900, x, y));
|
||||
}
|
||||
int mean = total / (size - 1);
|
||||
if (mean < lowest) lowest = mean;
|
||||
if (mean > highest) highest = mean;
|
||||
}
|
||||
return highest - lowest;
|
||||
};
|
||||
|
||||
int uprightAcrossColumns = axisSpread(upright, true);
|
||||
int uprightAcrossRows = axisSpread(upright, false);
|
||||
CHECK(uprightAcrossColumns > uprightAcrossRows);
|
||||
|
||||
int flatAcrossRows = axisSpread(board, false);
|
||||
int flatAcrossColumns = axisSpread(board, true);
|
||||
CHECK(flatAcrossRows > flatAcrossColumns);
|
||||
}
|
||||
|
||||
// A ladder without gaps is a plank. Every cutout lattice has to leave real
|
||||
// openings and still keep enough bar to stand on.
|
||||
VF_TEST(latticeTilesLeaveOpeningsBetweenTheirBars) {
|
||||
TileSampler sampler;
|
||||
int size = sampler.params().tileSize;
|
||||
int checked = 0;
|
||||
for (int tile = 0; tile < renderedTiles(sampler); ++tile) {
|
||||
const TileSpec& spec = sampler.palette().specFor(tile);
|
||||
if (spec.pattern != TilePattern::Lattice || !spec.cutout) continue;
|
||||
++checked;
|
||||
int holes = 0;
|
||||
for (int y = 0; y < size; ++y) {
|
||||
for (int x = 0; x < size; ++x) {
|
||||
if (sampler.pixelAt(tile, x, y).a == 0) ++holes;
|
||||
}
|
||||
}
|
||||
float openFraction = static_cast<float>(holes) / static_cast<float>(size * size);
|
||||
CHECK(openFraction > 0.15f);
|
||||
CHECK(openFraction < 0.92f);
|
||||
if (openFraction <= 0.15f || openFraction >= 0.92f) {
|
||||
std::printf(" tile %d (%s) is %.2f open\n", tile, spec.name,
|
||||
static_cast<double>(openFraction));
|
||||
}
|
||||
}
|
||||
CHECK(checked >= 8);
|
||||
}
|
||||
|
||||
// Veins have to be visible without swallowing the host rock, or every ore looks
|
||||
// like a solid block of its own metal.
|
||||
VF_TEST(oreVeinsCoverPartOfTheHostRockWithoutSwallowingIt) {
|
||||
TileSampler sampler;
|
||||
int size = sampler.params().tileSize;
|
||||
int checked = 0;
|
||||
for (int tile = 0; tile < renderedTiles(sampler); ++tile) {
|
||||
const TileSpec& spec = sampler.palette().specFor(tile);
|
||||
if (spec.pattern != TilePattern::OreSpeckle) continue;
|
||||
++checked;
|
||||
int vein = 0;
|
||||
for (int y = 0; y < size; ++y) {
|
||||
for (int x = 0; x < size; ++x) {
|
||||
if (leansToAccent(sampler.pixelAt(tile, x, y), spec)) ++vein;
|
||||
}
|
||||
}
|
||||
float coverage = static_cast<float>(vein) / static_cast<float>(size * size);
|
||||
CHECK(coverage > 0.02f);
|
||||
CHECK(coverage < 0.55f);
|
||||
if (coverage <= 0.02f || coverage >= 0.55f) {
|
||||
std::printf(" tile %d (%s) vein coverage %.3f\n", tile, spec.name,
|
||||
static_cast<double>(coverage));
|
||||
}
|
||||
}
|
||||
CHECK(checked >= 9);
|
||||
}
|
||||
Reference in new issue
Block a user