@threlte/xr
Version:
Tools to more easily create VR and AR experiences with Threlte
47 lines (46 loc) • 1.8 kB
JavaScript
import { Group, Matrix4, Vector3 } from 'three';
import { useThrelte, useTask, useStage } from '@threlte/core';
import { isPresenting } from './state.svelte.js';
import { useXROrigin } from '../hooks/useXROrigin.svelte.js';
export const headset = new Group();
const poseMatrix = new Matrix4();
const tempScale = new Vector3();
export const setupHeadset = () => {
const { renderer, camera, renderStage } = useThrelte();
const stage = useStage(Symbol('xr-headset-stage'), { before: renderStage });
const xrOrigin = useXROrigin();
const { xr } = renderer;
useTask(() => {
const space = xr.getReferenceSpace();
if (space === null)
return;
const pose = xr.getFrame().getViewerPose(space);
// Although pose is only typed as possibly undefined,
// It can be null on android chrome when using phone AR.
if (pose === undefined || pose === null)
return;
const origin = xrOrigin.current;
if (origin === undefined) {
const { position, orientation } = pose.transform;
headset.position.copy(position);
headset.quaternion.copy(orientation);
}
else {
origin.updateWorldMatrix(true, false);
poseMatrix.fromArray(pose.transform.matrix).premultiply(origin.matrixWorld);
poseMatrix.decompose(headset.position, headset.quaternion, tempScale);
}
}, {
autoInvalidate: false,
stage,
running: () => isPresenting.current
});
useTask(() => {
camera.current.getWorldPosition(headset.position);
camera.current.getWorldQuaternion(headset.quaternion);
}, {
autoInvalidate: false,
stage,
running: () => isPresenting.current === false
});
};