Add dev ghost-freeze (static spawn position) to isolate tracking jitter from float animation; toggle via tracking HUD tap

This commit is contained in:
2026-08-04 14:19:54 +10:00
parent e8d6a2f4b6
commit 1610e4b1e6
+23 -4
View File
@@ -28,6 +28,12 @@ const CAM_CORR = {
const CAM_MODES = ['none', 'y180', 'x180', 'z180'];
let camMode = 'none'; // default: none — rely on pose.js conjugation alone
/* Diagnostic: freeze all ghost motion (bob/sway/wander/path) so ghosts sit at their
* static spawn position. Lets you tell tracking jitter apart from the built-in float
* animation — if a frozen ghost still moves, that's the camera pose, not the ghost.
* Defaults ON in dev; tap the bottom third of the HUD tracking line to toggle. */
let freezeGhosts = false;
let info = { mode: 'dev' };
let scene3, camera3, renderer, video, canvas2d, ctx2d;
let detector, poseEst, fuser;
@@ -55,7 +61,7 @@ function updateDbg(fusedQuat, markerCount, spread) {
const v3 = v => `(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`;
const spreadLine = markerCount > 1 ? ` spread ${spread.toFixed(1)}cm` : '';
dbgEl.textContent =
`rot ${getRotMode()} cam ${camMode} (tap to cycle)\n` +
`rot ${getRotMode()} cam ${camMode} ${freezeGhosts ? 'FROZEN' : 'moving'}\n` +
`markers ${markerCount}${spreadLine}\n${rawLine}\nview ${v3(view)}\nup ${v3(up)}\n` +
`pos ${v3(camera3.position)}`;
}
@@ -139,6 +145,7 @@ async function start() {
// dev-mode pose readout + tap-to-cycle correction modes
if (info.mode === 'dev') {
freezeGhosts = true; // start static so tracking jitter is isolated from ghost float
dbgEl = $('#dbg');
if (dbgEl) {
dbgEl.style.display = 'block';
@@ -155,6 +162,12 @@ async function start() {
}
});
}
// tap the tracking HUD chip to toggle ghost motion freeze
const trk = $('#trk');
if (trk) {
trk.style.pointerEvents = 'auto';
trk.addEventListener('click', () => { freezeGhosts = !freezeGhosts; });
}
}
// network
@@ -278,10 +291,16 @@ function loop(t) {
const now = Date.now() + clockOffset;
for (const { rec, group } of activeGhosts.values()) {
ghostTransform(rec, now, _tmp);
group.position.copy(_tmp.position);
group.rotation.y = _tmp.rotationY;
if (freezeGhosts) {
// hold at the static spawn position; keep only the fade opacity from _tmp
group.position.set(rec.pos[0], rec.pos[1], rec.pos[2]);
group.rotation.y = 0;
} else {
group.position.copy(_tmp.position);
group.rotation.y = _tmp.rotationY;
}
group.userData.setOpacity(_tmp.opacity * 0.92);
group.userData.tick(t / 1000);
group.userData.tick(freezeGhosts ? 0 : t / 1000);
}
// HUD