From 0aa31ed6ad738629c2cb91b826aa25a851bc4b09 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 9 May 2026 13:38:57 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/pages/XRSession.tsx | 44 ++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/pages/XRSession.tsx b/src/pages/XRSession.tsx index 36e4410..b9c02cc 100644 --- a/src/pages/XRSession.tsx +++ b/src/pages/XRSession.tsx @@ -12,6 +12,7 @@ import { generateMarkerDownloadURL } from '@/lib/trackingMarker'; import { XRHud } from '@/components/XRHud'; import { findNearestVertex } from '@/components/three/SmartMeasure'; import { XRHitTestPlacement } from '@/components/three/XRHitTestPlacement'; +import { XRGrabbable } from '@/components/three/XRGrabbable'; // --- Diagnóstico XR --- console.log('[XR] Inicializando store...'); @@ -111,6 +112,7 @@ function XRModel({ url }: { url: string }) { const rotXRad = (fineTuning.rotX * Math.PI) / 180; const rotYRad = (fineTuning.rotY * Math.PI) / 180; const rotZRad = (fineTuning.rotZ * Math.PI) / 180; + const s = fineTuning.scale ?? 1; return ( @@ -128,6 +131,9 @@ function XRModel({ url }: { url: string }) { } // ─── ControllerFineTuning ────────────────────────────── +// Joystick for slow numeric adjustments. Disabled while any grip is held +// (grab takes priority). Trigger pressure modulates speed: light = fine, +// strong = fast. Standard VR mapping: left=lateral/forward, right=rotY/height. function ControllerFineTuning({ freeMove }: { freeMove: boolean }) { const { setFineTuning } = useModelStore(); const session = useXR((s) => s.session); @@ -139,37 +145,57 @@ function ControllerFineTuning({ freeMove }: { freeMove: boolean }) { let leftAxes: number[] | null = null; let rightAxes: number[] | null = null; + let leftTrig = 0; + let rightTrig = 0; let gripHeld = false; + let anyGripHeld = false; for (const source of inputSources) { const gp = source.gamepad; if (!gp) continue; - const gripButton = gp.buttons[2]; - if (gripButton && gripButton.pressed) gripHeld = true; + const gripBtn = gp.buttons[2]; + const trigBtn = gp.buttons[1]; + const gripVal = gripBtn ? (gripBtn.value || (gripBtn.pressed ? 1 : 0)) : 0; + if (gripBtn?.pressed) gripHeld = true; + if (gripVal > 0.3) anyGripHeld = true; // matches grab hysteresis OFF + const trigVal = trigBtn ? (trigBtn.value || (trigBtn.pressed ? 1 : 0)) : 0; if (source.handedness === 'left' && gp.axes.length >= 4) { leftAxes = [gp.axes[2], gp.axes[3]]; + leftTrig = trigVal; } if (source.handedness === 'right' && gp.axes.length >= 4) { rightAxes = [gp.axes[2], gp.axes[3]]; + rightTrig = trigVal; } } - // In freeMove mode, joystick always moves. Otherwise requires grip. + // Grab takes priority — joystick is disabled while grabbing + if (anyGripHeld) return; + // In freeMove mode, joystick always moves. Otherwise requires grip — but + // grip is reserved for grab now, so freeMove=false essentially disables. if (!freeMove && !gripHeld) return; - const posStep = 0.001; - const rotStep = 0.1; + const baseStep = 0.001; + const baseRot = 0.1; const deadzone = 0.15; + // Trigger modulation: 0 → 0.3×, 1 → 3× + const speedL = 0.3 + leftTrig * 2.7; + const speedR = 0.3 + rightTrig * 2.7; + // Quadratic acceleration on thumbstick value + const curve = (v: number) => Math.sign(v) * v * v; + const modelStore = useModelStore.getState(); const ft = { ...modelStore.fineTuning }; if (leftAxes) { - if (Math.abs(leftAxes[0]) > deadzone) ft.posX += leftAxes[0] * posStep; - if (Math.abs(leftAxes[1]) > deadzone) ft.posY -= leftAxes[1] * posStep; + // Left: X (horizontal) / Z forward-back (vertical, up = forward = -Z) + if (Math.abs(leftAxes[0]) > deadzone) ft.posX += curve(leftAxes[0]) * baseStep * speedL; + if (Math.abs(leftAxes[1]) > deadzone) ft.posZ += curve(leftAxes[1]) * baseStep * speedL; } if (rightAxes) { - if (Math.abs(rightAxes[1]) > deadzone) ft.posZ += rightAxes[1] * posStep; - if (Math.abs(rightAxes[0]) > deadzone) ft.rotY += rightAxes[0] * rotStep; + // Right: rotY (horizontal) / Y height (vertical, up = up) + if (Math.abs(rightAxes[0]) > deadzone) ft.rotY += curve(rightAxes[0]) * baseRot * speedR; + if (Math.abs(rightAxes[1]) > deadzone) ft.posY -= curve(rightAxes[1]) * baseStep * speedR; } setFineTuning(ft);