From 8307c7b11ebf0d44d89eb3955e708fb8958072d5 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Tue, 12 May 2026 11:01:34 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/hooks/useControllerGrab.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/hooks/useControllerGrab.ts b/src/hooks/useControllerGrab.ts index 63c8c62..b41f2de 100644 --- a/src/hooks/useControllerGrab.ts +++ b/src/hooks/useControllerGrab.ts @@ -1,6 +1,8 @@ import { useRef } from 'react'; import { useFrame, useThree } from '@react-three/fiber'; import * as THREE from 'three'; +// DEVKIT: remove this import + the fake-input block in useFrame to strip devkit +import { fakeInput, isFakeActive } from '@/devkit/fakeInputStore'; export interface GrabState { /** Analog grip pressure (0..1) */ @@ -50,6 +52,26 @@ export function useControllerGrab() { const { gl } = useThree(); useFrame((_state, _delta, frame: XRFrame | undefined) => { + // DEVKIT: fake-input branch — bypasses real WebXR when SimXR is active. + if (isFakeActive()) { + for (const hand of ['left', 'right'] as const) { + const fake = fakeInput[hand]; + const slot = ref.current[hand]; + slot.gripValue = fake.gripValue; + slot.triggerValue = fake.triggerValue; + slot.hasPose = fake.hasPose; + slot.gripWorld.copy(fake.gripWorld); + if (!slot.isGrabbing && fake.gripValue > GRAB_ON) { + slot.isGrabbing = true; + console.log(`[XR][grab] ▶ ${hand} START (fake v=${fake.gripValue.toFixed(2)})`); + } else if (slot.isGrabbing && fake.gripValue < GRAB_OFF) { + slot.isGrabbing = false; + console.log(`[XR][grab] ◼ ${hand} END (fake)`); + } + } + return; + } + if (!frame) return; const session = frame.session; const referenceSpace = gl.xr.getReferenceSpace();