Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-24 20:31:04 +00:00
parent d110dcb32c
commit e444a3a20f
+31 -4
View File
@@ -53,8 +53,9 @@ const FACE_DEFS: { label: string; dir: [number, number, number] }[] = [
{ label: 'ATRÁS', dir: [ 0, 0,-1] }, { label: 'ATRÁS', dir: [ 0, 0,-1] },
]; ];
function CubeMesh({ calibrating }: { calibrating: boolean }) { function CubeMesh({ calibrating, activeModelId }: { calibrating: boolean; activeModelId: string | null }) {
const meshRef = useRef<THREE.Mesh>(null); const meshRef = useRef<THREE.Mesh>(null);
const groupRef = useRef<THREE.Group>(null);
const { camera: localCam } = useThree(); const { camera: localCam } = useThree();
const [hover, setHover] = useState<number | null>(null); const [hover, setHover] = useState<number | null>(null);
@@ -86,6 +87,21 @@ function CubeMesh({ calibrating }: { calibrating: boolean }) {
}); });
}, [hover, materials]); }, [hover, materials]);
// Reusable temp objects for the per-frame model-quaternion sync.
const modelQuat = useMemo(() => new THREE.Quaternion(), []);
/** Returns the active model's current world quaternion (fineTuning rotation
* + calibration). Used to keep the cube glued to the piece's pose. */
const getModelWorldQuat = (): THREE.Quaternion => {
const g = getModelLocalGroup(activeModelId);
if (g) {
g.updateWorldMatrix(true, false);
g.getWorldQuaternion(modelQuat);
return modelQuat;
}
modelQuat.identity();
return modelQuat;
};
useFrame(() => { useFrame(() => {
const main = mainCameraRef.current; const main = mainCameraRef.current;
const controls = mainControlsRef.current; const controls = mainControlsRef.current;
@@ -95,6 +111,11 @@ function CubeMesh({ calibrating }: { calibrating: boolean }) {
localCam.position.copy(dir.multiplyScalar(3)); localCam.position.copy(dir.multiplyScalar(3));
localCam.up.copy(main.up); localCam.up.copy(main.up);
localCam.lookAt(0, 0, 0); localCam.lookAt(0, 0, 0);
// Sync the cube group orientation with the active model so it always
// mirrors the piece's pose (rotation from Posicionar, calibration, etc).
if (groupRef.current) {
groupRef.current.quaternion.copy(getModelWorldQuat());
}
}); });
const onClick = (e: ThreeEvent<MouseEvent>) => { const onClick = (e: ThreeEvent<MouseEvent>) => {
@@ -103,17 +124,21 @@ function CubeMesh({ calibrating }: { calibrating: boolean }) {
if (idx == null) return; if (idx == null) return;
const def = FACE_DEFS[idx]; const def = FACE_DEFS[idx];
if (!def) return; if (!def) return;
const dirVec = new THREE.Vector3(...def.dir); // Convert the local cube-face direction to world space using the model's
// current world quaternion — this keeps cube ↔ model coherent after any
// rotation/translation/reset of the piece.
const dirWorld = new THREE.Vector3(...def.dir).applyQuaternion(getModelWorldQuat()).normalize();
if (calibrating) { if (calibrating) {
pushCubeFace(dirVec); pushCubeFace(dirWorld);
} else { } else {
requestView(dirVec); requestView(dirWorld);
} }
}; };
// 70% of previous 1.4 → ~0.98 // 70% of previous 1.4 → ~0.98
const SIZE = 0.98; const SIZE = 0.98;
return ( return (
<group ref={groupRef}>
<mesh <mesh
ref={meshRef} ref={meshRef}
material={materials} material={materials}
@@ -127,6 +152,8 @@ function CubeMesh({ calibrating }: { calibrating: boolean }) {
> >
<boxGeometry args={[SIZE, SIZE, SIZE]} /> <boxGeometry args={[SIZE, SIZE, SIZE]} />
</mesh> </mesh>
<AxisTripod />
</group>
); );
} }