feat: initialize sunrise with 100-player shared rooms
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { Mesh, MeshStandardMaterial } from 'three';
|
||||
import { createBuildings } from '../src/scene/buildings.ts';
|
||||
import { loadBuildingAssets, createBakedBuildings } from '../src/scene/buildingAssets.ts';
|
||||
|
||||
test('saved buildings load without GeoJSON and preserve geometry and lighting exactly', async (t) => {
|
||||
const requested: string[] = [];
|
||||
t.mock.method(globalThis, 'fetch', async (input: string) => {
|
||||
requested.push(input);
|
||||
const path = new URL(input, 'http://localhost').pathname;
|
||||
return new Response(readFileSync(new URL(`../public${path}`, import.meta.url)));
|
||||
});
|
||||
const metadata = JSON.parse(readFileSync(new URL('../public/terrain/gwanaksan.json', import.meta.url), 'utf8'));
|
||||
const bytes = readFileSync(new URL('../public/terrain/gwanaksan.f32', import.meta.url));
|
||||
const terrain = { metadata, heights: new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / 4) };
|
||||
const data = JSON.parse(readFileSync(new URL('../public/buildings/gwacheon.geojson', import.meta.url), 'utf8'));
|
||||
const saved = await loadBuildingAssets();
|
||||
assert.equal(requested.length, 2);
|
||||
assert.ok(requested.every(path => !path.includes('.geojson')));
|
||||
const baked = createBakedBuildings(saved, metadata);
|
||||
const original = createBuildings(data, terrain);
|
||||
try {
|
||||
assert.deepEqual(baked.counts, original.counts);
|
||||
assert.deepEqual(baked.target, original.target);
|
||||
assert.equal(baked.group.children.length, original.group.children.length);
|
||||
for (const [i, child] of baked.group.children.entries()) {
|
||||
const actual = child as Mesh, expected = original.group.children[i] as Mesh;
|
||||
assert.equal(actual.name, expected.name);
|
||||
for (const name of ['position', 'normal', 'buildingLightHeight']) {
|
||||
assert.deepEqual(actual.geometry.getAttribute(name).array, expected.geometry.getAttribute(name).array);
|
||||
}
|
||||
assert.deepEqual(actual.geometry.index!.array, expected.geometry.index!.array);
|
||||
expected.geometry.computeBoundingBox(); expected.geometry.computeBoundingSphere();
|
||||
assert.deepEqual(actual.geometry.boundingBox, expected.geometry.boundingBox);
|
||||
assert.deepEqual(actual.geometry.boundingSphere, expected.geometry.boundingSphere);
|
||||
assert.equal((actual.material as MeshStandardMaterial).color.getHex(), (expected.material as MeshStandardMaterial).color.getHex());
|
||||
}
|
||||
assert.deepEqual(baked.spill.texture.image.data, original.spill.texture.image.data);
|
||||
assert.deepEqual(baked.spill.bounds, original.spill.bounds);
|
||||
for (const altitude of [-8, 0, 6, -8]) {
|
||||
baked.update(altitude); original.update(altitude);
|
||||
assert.equal(baked.spill.intensity.value, original.spill.intensity.value);
|
||||
}
|
||||
assert.throws(() => createBakedBuildings(saved, { ...metadata, observerSurfaceElevation: metadata.observerSurfaceElevation + 1 }), /지형/);
|
||||
assert.throws(() => createBakedBuildings({ ...saved, buffer: saved.buffer.slice(4) }, metadata), /건물/);
|
||||
} finally { baked.dispose(); original.dispose(); }
|
||||
});
|
||||
Reference in New Issue
Block a user