🚀 Auto-deploy: melhoria no snap e medição AR em 04/08/2026 21:26:18

This commit is contained in:
2026-08-04 21:26:18 +00:00
parent 028221ab04
commit 797fddb5a2
+36 -4
View File
@@ -6,6 +6,7 @@ import {
Grid, Grid,
Environment, Environment,
PerspectiveCamera, PerspectiveCamera,
Text
} from "@react-three/drei"; } from "@react-three/drei";
import { XR, useXR } from "@react-three/xr"; import { XR, useXR } from "@react-three/xr";
import { xrStore as store } from "@/stores/useXRStore"; import { xrStore as store } from "@/stores/useXRStore";
@@ -42,6 +43,35 @@ const CUBE_SIZE = 0.3;
type AlignPhase = 'IDLE' | 'WAIT_SURFACE' | 'WAIT_FACE2' | 'WAIT_EDGE'; type AlignPhase = 'IDLE' | 'WAIT_SURFACE' | 'WAIT_FACE2' | 'WAIT_EDGE';
// ===================================================================
// COMPONENTE: AR HUD Messages (Mostra avisos flutuantes apenas no óculos)
// ===================================================================
const ARHudMessages = ({ alignPhase }: { alignPhase: AlignPhase }) => {
const session = useXR((s) => s.session);
if (!session) return null;
let msg = '';
if (alignPhase === 'IDLE') msg = 'Livre! Clique na face do cubo para iniciar.';
else if (alignPhase === 'WAIT_SURFACE') msg = 'Face gravada! Clique na mesa para apoiar.';
else if (alignPhase === 'WAIT_FACE2') msg = 'Apoiado! Clique noutra face do cubo.';
else if (alignPhase === 'WAIT_EDGE') msg = 'Ultimo passo! Clique na borda da mesa.';
return (
<group position={[0, 1.3, -0.5]}>
<Text
fontSize={0.06}
color="#fde047"
anchorX="center"
anchorY="middle"
outlineWidth={0.005}
outlineColor="#000000"
>
{msg}
</Text>
</group>
);
};
// =================================================================== // ===================================================================
// COMPONENTE: CuboControlado // COMPONENTE: CuboControlado
// =================================================================== // ===================================================================
@@ -174,10 +204,10 @@ const CubeControlado = ({
allowScale={false} allowScale={false}
lockedActive={lockedRef.current} lockedActive={lockedRef.current}
onSync={(deltaPos, deltaQuat, deltaScale) => { onSync={(deltaPos, deltaQuat, deltaScale) => {
// Matriz atual do cubo // Matriz atual do cubo (IMPORTANTE: mesh default usa ordem XYZ)
const mMesh = new THREE.Matrix4().compose( const mMesh = new THREE.Matrix4().compose(
new THREE.Vector3(posRef.current.x, posRef.current.y, posRef.current.z), new THREE.Vector3(posRef.current.x, posRef.current.y, posRef.current.z),
new THREE.Quaternion().setFromEuler(new THREE.Euler(rotRef.current.x, rotRef.current.y, rotRef.current.z, 'YXZ')), new THREE.Quaternion().setFromEuler(new THREE.Euler(rotRef.current.x, rotRef.current.y, rotRef.current.z, 'XYZ')),
new THREE.Vector3(scaleRef.current, scaleRef.current, scaleRef.current) new THREE.Vector3(scaleRef.current, scaleRef.current, scaleRef.current)
); );
@@ -193,10 +223,10 @@ const CubeControlado = ({
mCombined.decompose(finalPos, finalQuat, finalScale); mCombined.decompose(finalPos, finalQuat, finalScale);
posRef.current.x = finalPos.x; posRef.current.x = finalPos.x;
posRef.current.y = Math.max(0.5, finalPos.y); posRef.current.y = Math.max(0.15, finalPos.y);
posRef.current.z = finalPos.z; posRef.current.z = finalPos.z;
const euler = new THREE.Euler().setFromQuaternion(finalQuat, 'YXZ'); const euler = new THREE.Euler().setFromQuaternion(finalQuat, 'XYZ');
rotRef.current.x = euler.x; rotRef.current.x = euler.x;
rotRef.current.y = euler.y; rotRef.current.y = euler.y;
rotRef.current.z = euler.z; rotRef.current.z = euler.z;
@@ -509,6 +539,8 @@ const QuestCubeLab = () => {
onEdgeClick={handleEdgeClick} onEdgeClick={handleEdgeClick}
/> />
<ARHudMessages alignPhase={alignPhase} />
<Grid args={[20, 20]} cellSize={0.25} cellThickness={0.5} cellColor="#475569" sectionSize={1} sectionThickness={1} sectionColor="#94a3b8" fadeDistance={18} fadeStrength={1} infiniteGrid={false} position={[0, 0, 0]} /> <Grid args={[20, 20]} cellSize={0.25} cellThickness={0.5} cellColor="#475569" sectionSize={1} sectionThickness={1} sectionColor="#94a3b8" fadeDistance={18} fadeStrength={1} infiniteGrid={false} position={[0, 0, 0]} />
<mesh receiveShadow rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.001, 0]}> <mesh receiveShadow rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.001, 0]}>
<planeGeometry args={[20, 20]} /> <planeGeometry args={[20, 20]} />