diff --git a/public/js/exhibit.js b/public/js/exhibit.js index 54a9164..5dbd805 100644 --- a/public/js/exhibit.js +++ b/public/js/exhibit.js @@ -34,6 +34,26 @@ let tracking = { markers: 0, lastSeen: 0 }; const clockOffsetSamples = []; let clockOffset = 0; // serverNow - clientNow +// Debug pose readout (dev mode): shows the fused camera orientation so orientation +// bugs can be diagnosed from numbers instead of eyeballing. Filled each fused frame. +const _dbgEuler = new THREE.Euler(); +const _dbgV = new THREE.Vector3(); +let dbgEl = null; +function updateDbg(fusedQuat, markerCount) { + if (!dbgEl) return; + const deg = r => (r * 180 / Math.PI).toFixed(0).padStart(4); + // raw fused (CV-frame) orientation as YXZ euler + _dbgEuler.setFromQuaternion(fusedQuat, 'YXZ'); + const rawLine = `raw P${deg(_dbgEuler.x)} Y${deg(_dbgEuler.y)} R${deg(_dbgEuler.z)}`; + // after correction: camera view (-Z) and up (+Y) in world + const view = _dbgV.set(0, 0, -1).applyQuaternion(camera3.quaternion).clone(); + const up = _dbgV.set(0, 1, 0).applyQuaternion(camera3.quaternion).clone(); + const v3 = v => `(${v.x.toFixed(2)},${v.y.toFixed(2)},${v.z.toFixed(2)})`; + dbgEl.textContent = + `markers ${markerCount}\n${rawLine}\nview ${v3(view)}\nup ${v3(up)}\n` + + `pos ${v3(camera3.position)}`; +} + async function boot() { info = await (await fetch('/api/info')).json(); installErrorReporter(info.mode === 'dev'); @@ -111,6 +131,9 @@ async function start() { detector = createDetector(); fuser = new WorldFuser(); + // dev-mode pose readout + if (info.mode === 'dev') { dbgEl = $('#dbg'); if (dbgEl) dbgEl.style.display = 'block'; } + // network const net = new ExhibitNet(); net.on('scene', (m) => { @@ -220,6 +243,7 @@ function loop(t) { camera3.position.copy(fused.position); // convert OpenCV camera frame -> Three.js (OpenGL) camera frame camera3.quaternion.copy(fused.quaternion).multiply(CV_TO_GL); + updateDbg(fused.quaternion, fused.markerCount); } } }