Changes
Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com>
This commit is contained in:
@@ -53,6 +53,10 @@ export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
const leftCtrl = useXRInputSourceState('controller', 'left');
|
||||
const [open, setOpen] = useState(true);
|
||||
const [tab, setTab] = useState<Tab>('scene');
|
||||
/** When pinned, the panel stays fixed in world space and does NOT follow the head. */
|
||||
const [pinned, setPinned] = useState(true);
|
||||
/** Forces re-anchor on next frame (used by "trazer" / unpin→pin). */
|
||||
const reanchorRequested = useRef(true);
|
||||
|
||||
const panelRef = useRef<THREE.Group>(null);
|
||||
const wristRef = useRef<THREE.Group>(null);
|
||||
@@ -70,14 +74,29 @@ export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
lastABtn.current = pressed;
|
||||
}
|
||||
|
||||
// Floating panel ~70cm in front of head, yaw-locked, damped
|
||||
// Floating panel:
|
||||
// • If pinned and already anchored once → don't move it (fixed in space).
|
||||
// • If unpinned → continuously follow head with damping.
|
||||
// • On (re)anchor request → snap target once and stop.
|
||||
if (panelRef.current && open) {
|
||||
const fwd = new THREE.Vector3(0, -0.05, -0.7).applyQuaternion(camera.quaternion);
|
||||
targetPos.current.copy(camera.position).add(fwd);
|
||||
const wantPos = new THREE.Vector3().copy(camera.position).add(fwd);
|
||||
const euler = new THREE.Euler().setFromQuaternion(camera.quaternion, 'YXZ');
|
||||
targetQuat.current.setFromEuler(new THREE.Euler(0, euler.y, 0, 'YXZ'));
|
||||
panelRef.current.position.lerp(targetPos.current, 0.12);
|
||||
panelRef.current.quaternion.slerp(targetQuat.current, 0.18);
|
||||
const wantQuat = new THREE.Quaternion().setFromEuler(new THREE.Euler(0, euler.y, 0, 'YXZ'));
|
||||
|
||||
if (reanchorRequested.current) {
|
||||
targetPos.current.copy(wantPos);
|
||||
targetQuat.current.copy(wantQuat);
|
||||
panelRef.current.position.copy(wantPos);
|
||||
panelRef.current.quaternion.copy(wantQuat);
|
||||
reanchorRequested.current = false;
|
||||
} else if (!pinned) {
|
||||
targetPos.current.copy(wantPos);
|
||||
targetQuat.current.copy(wantQuat);
|
||||
panelRef.current.position.lerp(targetPos.current, 0.12);
|
||||
panelRef.current.quaternion.slerp(targetQuat.current, 0.18);
|
||||
}
|
||||
// pinned + already anchored → leave panel where it is.
|
||||
}
|
||||
|
||||
// Wrist toggle follows left controller
|
||||
@@ -102,7 +121,14 @@ export function XRHudInWorld(props: XRHudInWorldProps) {
|
||||
<WristToggle ref={wristRef} open={open} onToggle={() => setOpen((v) => !v)} />
|
||||
{open && (
|
||||
<group ref={panelRef}>
|
||||
<FloatingPanel tab={tab} setTab={setTab} {...props} />
|
||||
<FloatingPanel
|
||||
tab={tab}
|
||||
setTab={setTab}
|
||||
pinned={pinned}
|
||||
onTogglePin={() => setPinned((v) => !v)}
|
||||
onRecenter={() => { reanchorRequested.current = true; }}
|
||||
{...props}
|
||||
/>
|
||||
</group>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user