diff --git a/src/components/three/XRControllerMeasure.tsx b/src/components/three/XRControllerMeasure.tsx index d5ef45c..f4a3768 100644 --- a/src/components/three/XRControllerMeasure.tsx +++ b/src/components/three/XRControllerMeasure.tsx @@ -49,12 +49,21 @@ export function XRControllerMeasure() { const dwellStart = useRef(0); const dwellFired = useRef(false); + // Throttling: raycast + snap analysis are heavy on dense IFC models and + // running them every frame at 72fps can stall the Quest right after + // toggling "Medir" from the Ferramentas tab. We cap heavy work to ~24Hz. + // Trigger/A/B/L-trigger polling continues every frame for responsiveness. + const heavyFrame = useRef(0); + const cachedSnappedPoint = useRef(null); + const cachedSnapKind = useRef<'vertex' | 'edge' | 'surface' | 'hole'>('surface'); + useFrame((_state, _dt, frame: XRFrame | undefined) => { const measureMode = useModelStore.getState().measureMode; const selectionMode = useModelStore.getState().selectionMode; if (laserRef.current) laserRef.current.visible = false; if (tipRef.current) tipRef.current.visible = false; if ((!measureMode && !selectionMode) || !frame) return; + const doHeavy = (heavyFrame.current++ % 3) === 0; const session = frame.session; const refSpace = gl.xr.getReferenceSpace();