Preview: apply ghost height, keep name labels world-scale above scaled ghosts
This commit is contained in:
@@ -129,29 +129,34 @@ function buildStatics(scene) {
|
||||
// ---------- live ghosts ----------
|
||||
const active = new Map(); // uid -> { rec, group, label }
|
||||
let followUid = null;
|
||||
let ghostHeight = 4; // cm, from scene.ghostHeightCm
|
||||
const clockSamples = []; let clockOffset = 0;
|
||||
|
||||
async function addGhost(rec) {
|
||||
if (active.has(rec.uid)) return;
|
||||
const group = await buildGhost(rec, gradients, modelManifest);
|
||||
group.userData.setHeight(ghostHeight);
|
||||
const label = textSprite(rec.name, COLORS[rec.color] || '#fff');
|
||||
label.position.y = 28;
|
||||
group.add(label);
|
||||
scn.add(group);
|
||||
label.scale.set(20, 5, 1);
|
||||
scn.add(group); scn.add(label); // label stays world-scale, outside the scaled group
|
||||
active.set(rec.uid, { rec, group, label });
|
||||
renderList();
|
||||
}
|
||||
function removeGhost(uid) {
|
||||
const e = active.get(uid);
|
||||
if (!e) return;
|
||||
scn.remove(e.group);
|
||||
scn.remove(e.group); scn.remove(e.label);
|
||||
active.delete(uid);
|
||||
if (followUid === uid) followUid = null;
|
||||
renderList();
|
||||
}
|
||||
|
||||
const net = new ExhibitNet();
|
||||
net.on('scene', m => buildStatics(m.scene))
|
||||
net.on('scene', m => {
|
||||
buildStatics(m.scene);
|
||||
ghostHeight = m.scene.ghostHeightCm || 4;
|
||||
for (const e of active.values()) e.group.userData.setHeight(ghostHeight);
|
||||
})
|
||||
.on('active', async m => {
|
||||
for (const uid of [...active.keys()]) removeGhost(uid);
|
||||
for (const rec of m.ghosts) await addGhost(rec);
|
||||
@@ -208,12 +213,14 @@ fit();
|
||||
(function loop(t) {
|
||||
requestAnimationFrame(loop);
|
||||
const now = Date.now() + clockOffset;
|
||||
for (const { rec, group } of active.values()) {
|
||||
for (const { rec, group, label } of active.values()) {
|
||||
ghostTransform(rec, now, _tmp);
|
||||
group.position.copy(_tmp.position);
|
||||
group.rotation.y = _tmp.rotationY;
|
||||
group.userData.setOpacity(_tmp.opacity * 0.92);
|
||||
group.userData.tick(t / 1000);
|
||||
label.position.set(_tmp.position.x, _tmp.position.y + ghostHeight + 3, _tmp.position.z);
|
||||
label.material.opacity = _tmp.opacity;
|
||||
}
|
||||
if (followUid && active.has(followUid)) orbit.target.lerp(active.get(followUid).group.position, 0.08);
|
||||
orbit.update();
|
||||
|
||||
Reference in New Issue
Block a user