From ca9307b2fd4acbe9780cca7216c189307052ebf8 Mon Sep 17 00:00:00 2001 From: jessikitty Date: Wed, 8 Jul 2026 12:34:53 +1000 Subject: [PATCH] Axis Correction --- public/js/exhibit.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/public/js/exhibit.js b/public/js/exhibit.js index 0cae294..734a63f 100644 --- a/public/js/exhibit.js +++ b/public/js/exhibit.js @@ -69,6 +69,13 @@ function centredCorners(m, w, h) { } // Build the marker->camera matrix (POS-IT), converting js-aruco axes to three.js. +// POS-IT frame is right-handed (X right, Y up, Z toward viewer). To bring the +// full RIGID transform into three.js we must CONJUGATE by F = diag(1,-1,-1): +// M_three = F * M_pose * F +// Premultiplying by F alone flips the translation but leaves the rotation's +// pitch inverted -> "camera up/down moves the ghost the wrong way". The second +// (right) multiply by F fixes the rotation handedness while keeping translation +// correct (F*M*F's translation column is F*t, i.e. flipped exactly once). const flipYZ = new THREE.Matrix4().makeScale(1, -1, -1); function markerToCameraMatrix(m) { const pose = posit.pose(centredCorners(m, grab.width, grab.height)); @@ -80,7 +87,8 @@ function markerToCameraMatrix(m) { R[2][0], R[2][1], R[2][2], t[2], 0, 0, 0, 1 ); - M.premultiply(flipYZ); + M.premultiply(flipYZ); // F * M + M.multiply(flipYZ); // F * M * F (conjugation: fixes pitch handedness) return { M, err: pose.bestError, dist: Math.hypot(t[0], t[1], t[2]) }; }