feat: initialize sunrise with 100-player shared rooms
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { Vector3 } from 'three';
|
||||
import { isCoastalLand, seaHeight, createOceanGeometry } from '../src/scene/coast.ts';
|
||||
import type { CoastData } from '../src/scene/coast.ts';
|
||||
import { terrainHeightAt, validateTerrain } from '../src/scene/terrainGeometry.ts';
|
||||
import { COAST } from '../src/constants/coast.ts';
|
||||
import { LOCATIONS } from '../src/constants/locations.ts';
|
||||
import { walkingHeight } from '../src/controls/walking.ts';
|
||||
import { structurePosition } from '../src/scene/structures.ts';
|
||||
const base = new URL('../public/terrain/hajodae/', import.meta.url);
|
||||
const coast: CoastData = JSON.parse(readFileSync(new URL('coast.json', base), 'utf8'));
|
||||
const meta = JSON.parse(readFileSync(new URL('metadata.json', base), 'utf8'));
|
||||
const b = readFileSync(new URL('heights.f32', base));
|
||||
const heights = new Float32Array(b.buffer.slice(b.byteOffset,b.byteOffset+b.byteLength));
|
||||
|
||||
test('Hajodae extraction has complete bounded coverage and a dry pavilion origin', () => {
|
||||
validateTerrain(meta, heights, COAST);
|
||||
assert.equal(meta.radiusMeters,1500);
|
||||
assert.equal(heights.byteLength,362404);
|
||||
assert.ok(isCoastalLand(coast,0,0));
|
||||
assert.ok(terrainHeightAt(meta, heights,0,0)>0);
|
||||
assert.ok(heights.every(Number.isFinite));
|
||||
assert.equal(meta.corrections.osmHeightCorrection,false);
|
||||
const shore = structurePosition(38.0231,128.72599,coast.origin);
|
||||
assert.ok(isCoastalLand(coast,shore.x,shore.z));
|
||||
assert.ok(walkingHeight(meta,heights,shore.x,shore.z) >= seaHeight(shore.x,shore.z,meta.observerSurfaceElevation)-0.001,
|
||||
'the near-shore land sample must not be pulled down by offshore vertices');
|
||||
assert.equal(isCoastalLand(coast,400,0),false,'east of the beach is sea');
|
||||
const cape=structurePosition(38.021987,128.7355911,coast.origin);
|
||||
assert.ok(isCoastalLand(coast,cape.x,cape.z),'lighthouse headland is land');
|
||||
assert.equal(isCoastalLand(coast,1600,0),false,'walking is limited to surveyed coverage');
|
||||
});
|
||||
|
||||
test('Hajodae view uses the pavilion and faces the pine reference east-northeast', () => {
|
||||
assert.deepEqual(meta.origin, {latitude:38.020813,longitude:128.7352564});
|
||||
assert.deepEqual(LOCATIONS.hajodae.coast.lookTarget, COAST.pine);
|
||||
const pine = structurePosition(COAST.pine.latitude, COAST.pine.longitude, meta.origin);
|
||||
const azimuth = Math.atan2(pine.x,-pine.z)*180/Math.PI;
|
||||
assert.ok(azimuth > 75 && azimuth < 80);
|
||||
});
|
||||
|
||||
test('ocean follows terrain curvature and faces upward', () => {
|
||||
const h=meta.observerSurfaceElevation;
|
||||
assert.equal(seaHeight(0,0,h),-h);
|
||||
assert.ok(seaHeight(1000,0,h)<-h);
|
||||
const g=createOceanGeometry(h);
|
||||
const p=g.getAttribute('position'), n=g.getAttribute('normal');
|
||||
assert.ok(n.getY(Math.floor(n.count/2))>0);
|
||||
for (const i of [0,Math.floor(p.count/2),p.count-1]) {
|
||||
assert.ok(Math.abs(p.getY(i)-seaHeight(p.getX(i),p.getZ(i),h))<0.001);
|
||||
}
|
||||
const v=new Vector3().fromBufferAttribute(p,0);
|
||||
assert.ok(Number.isFinite(v.length()));
|
||||
g.dispose();
|
||||
});
|
||||
Reference in New Issue
Block a user