80 lines
2.5 KiB
TypeScript
80 lines
2.5 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import sharp from "sharp";
|
|
import { OpaqueIndex, QuadBuffer } from "../renderer/mesh-buffers.mjs";
|
|
import { assertTerrainImage } from "../renderer/image-validation.mjs";
|
|
|
|
test("opaque sections preserve negative coordinates and do not alias adjacent boundaries", () => {
|
|
const index = new OpaqueIndex(
|
|
{ minX: -32, minZ: -32, maxX: 32, maxZ: 32 },
|
|
-32,
|
|
32,
|
|
);
|
|
const expected = new Set<string>();
|
|
for (let x = -32; x <= 32; x++) {
|
|
for (let y = -32; y <= 32; y++) {
|
|
for (let z = -32; z <= 32; z++) {
|
|
if ((x * 3 + y * 7 + z * 11) % 23 === 0) {
|
|
index.add(x, y, z);
|
|
expected.add(`${x},${y},${z}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (let x = -33; x <= 49; x++) {
|
|
for (let y = -33; y <= 49; y++) {
|
|
for (let z = -33; z <= 49; z++) {
|
|
assert.equal(index.has(x, y, z), expected.has(`${x},${y},${z}`));
|
|
}
|
|
}
|
|
}
|
|
index.clear();
|
|
assert.equal(index.has(0, 0, 0), false);
|
|
});
|
|
|
|
test("geometry batches retain every quad through growth with valid triangle indices and bounds", () => {
|
|
const buffer = new QuadBuffer();
|
|
const face = {
|
|
positions: new Float64Array([0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0]),
|
|
uvs: new Float32Array([0, 0, 1, 0, 0, 1, 1, 1]),
|
|
normal: [0, 0, -1],
|
|
};
|
|
for (let i = 0; i < 4096; i++) buffer.add(face, i - 2048, 64, -1);
|
|
assert.equal(buffer.full, true);
|
|
assert.throws(() => buffer.add(face, 0, 0, 0), /full/);
|
|
const data = buffer.finish();
|
|
assert.equal(data.positions.length, 4096 * 12);
|
|
assert.equal(data.indices.length, 4096 * 6);
|
|
assert.equal(Math.max(...data.indices), 4096 * 4 - 1);
|
|
assert.deepEqual(
|
|
[...data.indices.slice(-6)],
|
|
[16380, 16381, 16382, 16382, 16381, 16383],
|
|
);
|
|
assert.deepEqual(data.min, [-2048, 64, -1]);
|
|
assert.deepEqual(data.max, [2048, 65, -1]);
|
|
});
|
|
|
|
test("sky-only WebP output is rejected instead of becoming a playable draft", async () => {
|
|
const sky = await sharp({
|
|
create: { width: 128, height: 128, channels: 3, background: "#95c4eb" },
|
|
})
|
|
.webp({ quality: 85 })
|
|
.toBuffer();
|
|
await assert.rejects(
|
|
assertTerrainImage(sky, "Surface map"),
|
|
/contains only sky/,
|
|
);
|
|
});
|
|
|
|
test("flat textured terrain is accepted even when its colors are nearly uniform", async () => {
|
|
const terrain = await sharp({
|
|
create: { width: 128, height: 128, channels: 3, background: "#719447" },
|
|
})
|
|
.webp()
|
|
.toBuffer();
|
|
assert.equal(
|
|
await assertTerrainImage(terrain, "Panorama p0, downward face"),
|
|
64 * 64,
|
|
);
|
|
});
|