@threlte/xr
Version:
Tools to more easily create VR and AR experiences with Threlte
63 lines (62 loc) • 2.28 kB
JavaScript
import { useController } from '../../hooks/useController.svelte.js';
import { useTeleport } from '../../hooks/useTeleport.js';
import { useFixed } from '../../internal/useFixed.js';
import { isPresenting, teleportIntersection } from '../../internal/state.svelte.js';
import { fromStore } from 'svelte/store';
export const setupTeleportControls = (context, handContext, fixedStep = 1 / 40) => {
const handedness = handContext.hand;
const enabled = fromStore(handContext.enabled);
const controller = fromStore(useController(handedness));
const teleport = useTeleport();
const handleHoverEnd = () => {
handContext.hovered.set(undefined);
teleportIntersection[handedness] = undefined;
};
const { start, stop } = useFixed(() => {
const gamepad = controller.current?.inputSource.gamepad;
if (gamepad === undefined) {
return;
}
const selecting = (gamepad.axes[3] ?? 0) < -0.8;
if (handContext.active.current && !selecting) {
handContext.active.set(false);
}
else if (!handContext.active.current && selecting) {
handContext.active.set(true);
}
if (!handContext.active.current) {
if (handContext.hovered.current !== undefined) {
teleport(handContext.hovered.current.point);
handleHoverEnd();
}
return;
}
handContext.compute(context, handContext);
const [intersect] = handContext.raycaster.intersectObjects(context.interactiveObjects, true);
if (intersect === undefined) {
if (handContext.hovered.current !== undefined) {
handleHoverEnd();
}
return;
}
if (context.blockers.has(intersect.object.uuid)) {
if (handContext.hovered.current !== undefined) {
handleHoverEnd();
}
return;
}
teleportIntersection[handedness] = intersect;
handContext.hovered.set(intersect);
}, {
fixedStep,
autoStart: false
});
$effect.pre(() => {
if (isPresenting.current && enabled.current) {
start();
}
else {
stop();
}
});
};