Character manager: asset uploads, per-ghost model/colour/opacity overrides, face+torso texture decals

This commit is contained in:
2026-07-24 14:47:36 +10:00
parent b6822af047
commit 5357c8464d
9 changed files with 642 additions and 39 deletions
+9 -2
View File
@@ -15,7 +15,7 @@ const $ = (s) => document.querySelector(s);
let info = { mode: 'dev' };
let scene3, camera3, renderer, video, canvas2d, ctx2d;
let detector, poseEst, fuser;
let gradients = {}, modelManifest = null;
let gradients = {}, modelManifest = null, characters = { defaults: {}, byId: {} };
let ghostHeight = 4; // cm, from scene.ghostHeightCm
const activeGhosts = new Map(); // uid -> { rec, group }
let tracking = { markers: 0, lastSeen: 0 };
@@ -29,6 +29,7 @@ async function boot() {
const g = await (await fetch('/api/ghosts')).json();
gradients = g.gradients.gradients || g.gradients;
modelManifest = await (await fetch('/api/models')).json();
characters = await (await fetch('/api/characters')).json();
$('#start').addEventListener('click', start, { once: true });
}
@@ -68,6 +69,12 @@ async function start() {
ghostHeight = m.scene.ghostHeightCm || 4;
for (const e of activeGhosts.values()) e.group.userData.setHeight(ghostHeight);
})
.on('characters', async (m) => {
characters = m.characters || characters;
const recs = [...activeGhosts.values()].map(e => e.rec);
for (const uid of [...activeGhosts.keys()]) removeGhost(uid);
for (const rec of recs) await addGhost(rec); // rebuild with new visuals
})
.on('active', async (m) => {
for (const uid of [...activeGhosts.keys()]) removeGhost(uid);
for (const rec of m.ghosts) await addGhost(rec);
@@ -111,7 +118,7 @@ function buildOcclusion(scene) {
// ---------- ghosts ----------
async function addGhost(rec) {
if (activeGhosts.has(rec.uid)) return;
const group = await buildGhost(rec, gradients, modelManifest);
const group = await buildGhost(rec, gradients, modelManifest, characters);
group.userData.setHeight(ghostHeight);
scene3.add(group);
activeGhosts.set(rec.uid, { rec, group });