diff --git a/public/js/ar/pose.js b/public/js/ar/pose.js index b986dd4..1a4766e 100644 --- a/public/js/ar/pose.js +++ b/public/js/ar/pose.js @@ -11,16 +11,16 @@ const _m = new THREE.Matrix4(); const _q = new THREE.Quaternion(); /* Rotation frame correction. The translation is converted from POS-IT's frame to - * the Three.js frame by F = diag(1,-1,-1) (the -t[1]/-t[2] negation). A rotation - * must be conjugated by the SAME F to stay in one consistent frame: R' = F R F^T. - * Applying F to translation but leaving rotation as-is (mode 'asis') puts position - * and orientation in different frames — position tracks but orientation tumbles - * (phone pitch leaks into world yaw/roll). Modes are runtime-switchable for on-device - * A/B: the debug overlay cycles ROT_MODES and calls setRotMode(). */ + * the Three.js frame by F = diag(1,-1,-1) (the -t[1]/-t[2] negation). The rotation + * needs a matching left-multiply by F: R' = F R. Confirmed on-device — orientation + * then survives phone rotation and viewing angle. (Leaving rotation as-is ('asis') + * puts position and orientation in different frames so pitch leaks into yaw/roll; + * the full conjugation F R F^T ('frf') over-corrects for this pipeline.) Modes stay + * runtime-switchable for future re-tuning; the debug overlay cycles ROT_MODES. */ const F = new THREE.Matrix4().set(1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1); const Ft = F.clone().transpose(); -export const ROT_MODES = ['frf', 'asis', 'fr', 'rf']; -let rotMode = 'frf'; // F R F^T — the frame-consistent default +export const ROT_MODES = ['fr', 'frf', 'asis', 'rf']; +let rotMode = 'fr'; // F R — confirmed correct on-device (orientation survives rotation/angle) export function setRotMode(m) { if (ROT_MODES.includes(m)) rotMode = m; } export function getRotMode() { return rotMode; }