Lock rotation mode to fr (F R) — confirmed correct on device

This commit is contained in:
2026-08-04 11:02:07 +10:00
parent f4d51b6def
commit 605f957f35
+8 -8
View File
@@ -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; }