Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
+35
-9
@@ -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 (
|
||||
<group
|
||||
@@ -121,6 +123,7 @@ function XRModel({ url }: { url: string }) {
|
||||
-modelInfo.center.z + fineTuning.posZ,
|
||||
]}
|
||||
rotation={[rotXRad, rotYRad, rotZRad]}
|
||||
scale={[s, s, s]}
|
||||
>
|
||||
<primitive object={scene} />
|
||||
</group>
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user