🚀 Auto-deploy: melhoria no snap e medição AR em 24/05/2026 12:38:19
This commit is contained in:
@@ -53,11 +53,15 @@ const WristToggle = forwardRef<THREE.Group, { open: boolean; onToggle: () => voi
|
||||
);
|
||||
|
||||
export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
const { camera } = useThree();
|
||||
const { camera, gl } = useThree();
|
||||
const leftCtrl = useXRInputSourceState('controller', 'left');
|
||||
const rightCtrl = useXRInputSourceState('controller', 'right');
|
||||
const [open, setOpen] = useState(true);
|
||||
const [tab, setTab] = useState<Tab>('scene');
|
||||
|
||||
const open = useModelStore((s) => s.xrHudOpen);
|
||||
const setOpen = useModelStore((s) => s.setXrHudOpen);
|
||||
const tab = useModelStore((s) => s.xrHudTab) as Tab;
|
||||
const setTab = useModelStore((s) => s.setXrHudTab) as unknown as (t: Tab) => void;
|
||||
|
||||
/** When pinned, the panel stays fixed in world space and does NOT follow the head. */
|
||||
const [pinned, setPinned] = useState(true);
|
||||
/** While true, the panel is glued to the right controller (drag mode). */
|
||||
@@ -82,7 +86,7 @@ export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
if (gp) {
|
||||
const aBtn = gp.buttons[4];
|
||||
const pressed = !!aBtn?.pressed;
|
||||
if (pressed && !lastABtn.current) setOpen((v) => !v);
|
||||
if (pressed && !lastABtn.current) setOpen(!open);
|
||||
lastABtn.current = pressed;
|
||||
}
|
||||
|
||||
@@ -150,11 +154,11 @@ export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
}
|
||||
}
|
||||
|
||||
// Head-locked fallback toggle — always visible in lower-left of FOV,
|
||||
// Head-locked fallback toggle — always visible in lower-right of FOV,
|
||||
// so the user can reopen the menu even without controllers or if the
|
||||
// panel is positioned out of view.
|
||||
if (headLockRef.current) {
|
||||
const offset = new THREE.Vector3(-0.18, -0.18, -0.5).applyQuaternion(camera.quaternion);
|
||||
const offset = new THREE.Vector3(0.18, -0.18, -0.5).applyQuaternion(camera.quaternion);
|
||||
headLockRef.current.position.copy(camera.position).add(offset);
|
||||
headLockRef.current.quaternion.copy(camera.quaternion);
|
||||
}
|
||||
@@ -165,16 +169,21 @@ export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<WristToggle ref={wristRef} open={open} onToggle={() => setOpen((v) => !v)} />
|
||||
{/* Head-locked fallback: always-visible quick controls in lower-left of FOV */}
|
||||
<WristToggle ref={wristRef} open={open} onToggle={() => setOpen(!open)} />
|
||||
{/* Head-locked fallback: always-visible quick controls in lower-right of FOV */}
|
||||
<group ref={headLockRef} renderOrder={999}>
|
||||
<XR3DButton position={[0, 0.018, 0]} size={[0.07, 0.022]}
|
||||
<XR3DButton position={[0, 0.026, 0]} size={[0.07, 0.022]}
|
||||
label={open ? '✕ Menu' : '☰ Menu'} active={open}
|
||||
onClick={() => { setOpen((v) => !v); reanchorRequested.current = true; }}
|
||||
onClick={() => { setOpen(!open); reanchorRequested.current = true; }}
|
||||
fontSize={0.0085} />
|
||||
<XR3DButton position={[0, -0.008, 0]} size={[0.07, 0.022]}
|
||||
<XR3DButton position={[0, 0, 0]} size={[0.07, 0.022]}
|
||||
label={showGrid ? 'Grid ON' : 'Grid OFF'} active={showGrid}
|
||||
onClick={() => setShowGrid(!showGrid)} fontSize={0.0085} />
|
||||
<XR3DButton position={[0, -0.026, 0]} size={[0.07, 0.022]}
|
||||
label="✕ Sair AR" active={false}
|
||||
onClick={() => {
|
||||
gl.xr.getSession()?.end();
|
||||
}} fontSize={0.0085} />
|
||||
<RecIndicator />
|
||||
</group>
|
||||
{open && (
|
||||
|
||||
@@ -299,6 +299,12 @@ interface ModelStore {
|
||||
xrFeatures: XRFeatureFlags;
|
||||
setXRFeature: (key: keyof XRFeatureFlags, value: boolean) => void;
|
||||
resetXRFeatures: () => void;
|
||||
|
||||
// ── WebXR HUD states persistent cache ────
|
||||
xrHudOpen: boolean;
|
||||
setXrHudOpen: (open: boolean) => void;
|
||||
xrHudTab: string;
|
||||
setXrHudTab: (tab: string) => void;
|
||||
}
|
||||
|
||||
/** Sync top-level legacy `model` / `fineTuning` from active SceneModel. */
|
||||
@@ -673,4 +679,9 @@ export const useModelStore = create<ModelStore>((set, get) => ({
|
||||
saveXRFeatures(next);
|
||||
set({ xrFeatures: next });
|
||||
},
|
||||
|
||||
xrHudOpen: true,
|
||||
setXrHudOpen: (open) => set({ xrHudOpen: open }),
|
||||
xrHudTab: 'scene',
|
||||
setXrHudTab: (tab) => set({ xrHudTab: tab }),
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user