From 5e7ff33a3e5db5edbb00bff49a64362b16cee450 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sun, 24 May 2026 20:06:43 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/components/three/ModelViewer.tsx | 47 +++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index 0b8cde3..651a66f 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -246,6 +246,18 @@ function GLBModel({ sceneModel, isActive }: { sceneModel: SceneModel; isActive: ? 'y' : 'z'; + // Calibration quaternion (applied innermost, around center). We render with identity + // while calibration is in progress for this model so face normals reflect the + // un-calibrated frame; the result is committed at the end. + const calQuatArr = sceneModel.calibrationQuat; + const isCalibratingThis = calibration.modelId === sceneModel.id && calibration.step !== 'idle' && calibration.step !== 'done'; + const calQuat = useMemo(() => { + if (isCalibratingThis) return new THREE.Quaternion(); + if (!calQuatArr) return new THREE.Quaternion(); + return new THREE.Quaternion(calQuatArr[0], calQuatArr[1], calQuatArr[2], calQuatArr[3]); + }, [calQuatArr, isCalibratingThis]); + const calGroupRef = useRef(null); + return ( 4) return; + // Calibration: capture model face normal in world space. + if ( + calibration.modelId === sceneModel.id && + (calibration.step === 'await-model-1' || calibration.step === 'await-model-2' || calibration.step === 'await-model-3') && + e.face && e.object + ) { + const n = e.face.normal.clone(); + const nm = new THREE.Matrix3().getNormalMatrix(e.object.matrixWorld); + n.applyMatrix3(nm).normalize(); + const wq = new THREE.Quaternion(); + (calGroupRef.current ?? e.object).getWorldQuaternion(wq); + pushModelFaceNormal(n, wq); + if (calibration.step === 'done') { + const q = computeCalibrationQuaternion(calibration.pairs); + if (q) { + useModelStore.getState().setCalibration(sceneModel.id, [q.x, q.y, q.z, q.w]); + } + } + return; + } + if (selectionMode) { const element = findElementRoot(e.object); if (element) { @@ -273,13 +306,13 @@ function GLBModel({ sceneModel, isActive }: { sceneModel: SceneModel; isActive: rotation={[rotXRad, rotYRad, rotZRad]} scale={[s, s, s]} > - {/* Shift geometry so its center sits at the parent's origin (pivot = center). - This is the local frame where measurement points are stored, so measurements - follow the model when posX/Y/Z or rotX/Y/Z change in "Posicionar" mode. */} - - - - + {/* Calibration rotation (innermost, around center). */} + + + + + +