60 lines
2.2 KiB
JavaScript
60 lines
2.2 KiB
JavaScript
import { TestCase } from "./framework/test_case.js";
|
|
import { generateWaterBump } from "../client/js/map_view/water.js";
|
|
|
|
export class WaterTest extends TestCase {
|
|
test_is_deterministic_for_a_seed() {
|
|
const first = generateWaterBump(64, 4, 7);
|
|
const second = generateWaterBump(64, 4, 7);
|
|
this.assertEqual(first.data, second.data, "the same seed bakes the same map");
|
|
const other = generateWaterBump(64, 4, 8);
|
|
this.assertNotEqual(first.data, other.data, "a new seed reshapes the cells");
|
|
}
|
|
|
|
test_the_map_is_the_requested_size() {
|
|
const bump = generateWaterBump(32, 4, 1);
|
|
this.assertEqual(bump.size, 32);
|
|
this.assertEqual(bump.data.length, 32 * 32 * 4, "RGBA bytes");
|
|
}
|
|
|
|
test_every_normal_is_unit_length() {
|
|
const bump = generateWaterBump(64, 5, 99);
|
|
for (let i = 0; i < bump.data.length; i += 4) {
|
|
const nx = (bump.data[i] / 255) * 2 - 1;
|
|
const ny = (bump.data[i + 1] / 255) * 2 - 1;
|
|
const nz = (bump.data[i + 2] / 255) * 2 - 1;
|
|
this.assertApprox(Math.hypot(nx, ny, nz), 1, 0.02, "the normal is unit length");
|
|
this.assertTrue(nz > 0, "the normal points out of the surface");
|
|
}
|
|
}
|
|
|
|
test_the_height_channel_varies() {
|
|
const bump = generateWaterBump(64, 5, 3);
|
|
let low = 255;
|
|
let high = 0;
|
|
for (let i = 3; i < bump.data.length; i += 4) {
|
|
low = Math.min(low, bump.data[i]);
|
|
high = Math.max(high, bump.data[i]);
|
|
}
|
|
this.assertGreater(high - low, 40, "the Voronoi crests and troughs span a range");
|
|
}
|
|
|
|
test_the_field_wraps_without_a_seam() {
|
|
// The feature points are wrapped and the normal uses wrapped differences,
|
|
// so the right-to-left seam must be no rougher than an interior step.
|
|
const bump = generateWaterBump(64, 4, 21);
|
|
const size = bump.size;
|
|
const columnDiff = (x0, x1) => {
|
|
let sum = 0;
|
|
for (let y = 0; y < size; y++) {
|
|
sum += Math.abs(bump.data[(y * size + x0) * 4] - bump.data[(y * size + x1) * 4]);
|
|
}
|
|
return sum / size;
|
|
};
|
|
let interior = 0;
|
|
for (let x = 0; x < size - 1; x++) interior += columnDiff(x, x + 1);
|
|
interior /= size - 1;
|
|
this.assertLess(columnDiff(size - 1, 0), interior * 4 + 4,
|
|
"the wrapping seam is no rougher than the interior");
|
|
}
|
|
}
|