From dab50732d6ceced2c9a825e445201e75edce2c5e Mon Sep 17 00:00:00 2001 From: Walter Perdan Date: Fri, 29 May 2026 21:28:11 +0200 Subject: [PATCH] Fix CV->GL pose conversion in updateTrackable() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop negating rotation columns 1 and 2 in updateTrackable(). The previous behavior applied a partial CV->GL conversion (rotation columns flipped, translation untouched), which left consumers with an inconsistent pose: the rotation was neither raw OpenCV nor a clean GL right-handed modelview, and the translation Z stayed positive — causing tracked objects to render behind the camera in OpenGL/three.js scenes (clip.w < 0, ndc.z > 1). After this change, getPoseMatrix2() / trans returns the raw OpenCV pose (rotation unmodified, translation kept at the existing 0.001 * 1.64 scale). The CV->GL handedness flip (negate Y and Z rows including translation) is applied downstream by arglCameraViewRHf when building the GL right-handed modelview (matrixGL_RH on the JS side, getGLViewMatrix() in WebARKitManager on the C++ side). Both downstream paths are now mathematically clean diag(1, -1, -1, 1) * pose conversions and produce a correct modelview that places the tracked object in front of the GL camera. Note: this is a semantic change to `pose` / `trans` for any consumer that relied on the previous partially-converted shape. Downstream consumers should use matrixGL_RH (or getGLViewMatrix) for OpenGL rendering and treat `pose` as the raw OpenCV camera pose. Refs: webarkit/WebARKitLib#34, webarkit/webarkit-testing#31 Co-Authored-By: Claude Opus 4.7 --- WebARKit/WebARKitPattern.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/WebARKit/WebARKitPattern.cpp b/WebARKit/WebARKitPattern.cpp index fc2368a..19878df 100644 --- a/WebARKit/WebARKitPattern.cpp +++ b/WebARKit/WebARKitPattern.cpp @@ -55,12 +55,18 @@ void WebARKitPatternTrackingInfo::getTrackablePose(cv::Mat& pose) { void WebARKitPatternTrackingInfo::updateTrackable() { if (transMat) { - //visible = true; + // Keep `trans` as the raw OpenCV pose (rotation unmodified, translation + // scaled). The CV->GL handedness conversion (negate Y and Z rows incl. + // translation) is applied downstream by arglCameraViewRHf when building + // the GL right-handed modelview (matrixGL_RH / getGLViewMatrix). + // Previously, rotation columns 1 and 2 were negated here but the + // translation was not, producing an inconsistent partial conversion + // that left tracked objects behind the camera in OpenGL renderers. for (int j = 0; j < 3; j++) { - trans[j][0] = transMat[j][0]; - trans[j][1] = -transMat[j][1]; - trans[j][2] = -transMat[j][2]; - trans[j][3] = (transMat[j][3] * m_scale * 0.001f * 1.64f ); + trans[j][0] = transMat[j][0]; + trans[j][1] = transMat[j][1]; + trans[j][2] = transMat[j][2]; + trans[j][3] = (transMat[j][3] * m_scale * 0.001f * 1.64f); } } }