78 lines
1.9 KiB
JavaScript
78 lines
1.9 KiB
JavaScript
|
|
import * as THREE from 'three';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Unified registry for named coordinates in the scene.
|
||
|
|
*
|
||
|
|
* Sources:
|
||
|
|
* - NAMED_LOCATIONS (static waypoints from locationsConfig.js)
|
||
|
|
* - sceneObjects registry (live GLB props from objectLoader.js)
|
||
|
|
*
|
||
|
|
* Scene-object positions are read live, so moving an object updates its
|
||
|
|
* resolved location automatically.
|
||
|
|
*/
|
||
|
|
|
||
|
|
function addDebugMarker(scene, name, position, color = 0xff3366) {
|
||
|
|
const marker = new THREE.Mesh(
|
||
|
|
new THREE.SphereGeometry(0.05, 16, 16),
|
||
|
|
new THREE.MeshBasicMaterial({ color }),
|
||
|
|
);
|
||
|
|
marker.position.set(...position);
|
||
|
|
marker.name = `__marker_${name}`;
|
||
|
|
scene.add(marker);
|
||
|
|
}
|
||
|
|
|
||
|
|
export function createLocationRegistry({
|
||
|
|
scene,
|
||
|
|
namedLocations = [],
|
||
|
|
sceneObjects = null,
|
||
|
|
debugMarkers = false,
|
||
|
|
}) {
|
||
|
|
const staticEntries = new Map();
|
||
|
|
|
||
|
|
for (const loc of namedLocations) {
|
||
|
|
const [x, y, z] = loc.position;
|
||
|
|
staticEntries.set(loc.name, {
|
||
|
|
name: loc.name,
|
||
|
|
description: loc.description ?? '',
|
||
|
|
source: 'named',
|
||
|
|
getPosition: () => ({ x, y, z }),
|
||
|
|
});
|
||
|
|
|
||
|
|
if (debugMarkers && scene) addDebugMarker(scene, loc.name, loc.position);
|
||
|
|
}
|
||
|
|
|
||
|
|
function get(name) {
|
||
|
|
if (staticEntries.has(name)) return staticEntries.get(name);
|
||
|
|
if (sceneObjects?.has(name)) {
|
||
|
|
const obj = sceneObjects.get(name);
|
||
|
|
return {
|
||
|
|
name,
|
||
|
|
description: `Scene object (${obj.url})`,
|
||
|
|
source: 'object',
|
||
|
|
getPosition: obj.getPosition,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
function all() {
|
||
|
|
const names = new Set(staticEntries.keys());
|
||
|
|
if (sceneObjects) for (const n of sceneObjects.keys()) names.add(n);
|
||
|
|
return [...names].map(get).filter(Boolean);
|
||
|
|
}
|
||
|
|
|
||
|
|
function describe() {
|
||
|
|
const out = {};
|
||
|
|
for (const loc of all()) {
|
||
|
|
out[loc.name] = {
|
||
|
|
position: loc.getPosition(),
|
||
|
|
source: loc.source,
|
||
|
|
description: loc.description,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
return { get, all, describe };
|
||
|
|
}
|