@react-three/xr
Version:
VR/AR for react-three-fiber
95 lines (94 loc) • 5.7 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { resolveInputSourceImplementation } from '@pmndrs/xr/internals';
import { context, reconciler, useStore } from '@react-three/fiber';
import { Suspense, useMemo } from 'react';
import { shallow } from 'zustand/shallow';
import { xrInputSourceStateContext, xrSpaceContext } from './contexts.js';
import { DefaultXRController, DefaultXRGaze, DefaultXRHand, DefaultXRScreenInput, DefaultXRTransientPointer, } from './default.js';
import { useXRSessionVisibilityState } from './hooks.js';
import { XRSpace } from './space.js';
import { objectToKey } from './utils.js';
import { useXR } from './xr.js';
export function XRElements({ children }) {
const referenceSpace = useXR((xr) => xr.originReferenceSpace);
const origin = useXR((xr) => xr.origin);
const visible = useXRSessionVisibilityState() === 'visible';
const store = useStore();
const storeWithOriginAsScene = useMemo(() => Object.assign({}, store, {
getState() {
return { ...store.getState(), scene: origin };
},
}), [origin, store]);
if (origin == null || referenceSpace == null) {
return null;
}
return (_jsx(_Fragment, { children: reconciler.createPortal(_jsx(context.Provider, { value: store, children: _jsxs(xrSpaceContext.Provider, { value: referenceSpace, children: [_jsxs("group", { matrixAutoUpdate: false, visible: visible, children: [_jsx(XRControllers, {}), _jsx(XRHands, {}), _jsx(XRTransientPointers, {}), _jsx(XRGazes, {}), _jsx(XRScreenInputs, {})] }), children] }) }), storeWithOriginAsScene, null) }));
}
function XRControllers() {
const controllerStates = useXR((xr) => xr.inputSourceStates.filter((state) => state.type === 'controller'), shallow);
let Implementation = useXR((xr) => xr.controller);
if (Implementation === false) {
return null;
}
return (_jsx(_Fragment, { children: controllerStates.map((state) => {
const ResolvedImpl = resolveInputSourceImplementation(Implementation, state.inputSource.handedness, {});
if (ResolvedImpl === false) {
return null;
}
return (_jsx(xrInputSourceStateContext.Provider, { value: state, children: _jsx(XRSpace, { space: "target-ray-space", children: _jsx(Suspense, { children: typeof ResolvedImpl === 'function' ? _jsx(ResolvedImpl, {}) : _jsx(DefaultXRController, { ...ResolvedImpl }) }) }) }, state.id));
}) }));
}
function XRHands() {
const handStates = useXR((xr) => xr.inputSourceStates.filter((state) => state.type === 'hand'), shallow);
const Implementation = useXR((xr) => xr.hand);
if (Implementation === false) {
return null;
}
return (_jsx(_Fragment, { children: handStates.map((state) => {
const ResolvedImpl = resolveInputSourceImplementation(Implementation, state.inputSource.handedness, {});
if (ResolvedImpl === false) {
return null;
}
return (_jsx(xrInputSourceStateContext.Provider, { value: state, children: _jsx(XRSpace, { space: "target-ray-space", children: _jsx(Suspense, { children: typeof ResolvedImpl === 'function' ? _jsx(ResolvedImpl, {}) : _jsx(DefaultXRHand, { ...ResolvedImpl }) }) }) }, objectToKey(state)));
}) }));
}
function XRTransientPointers() {
const transientPointerStates = useXR((xr) => xr.inputSourceStates.filter((state) => state.type === 'transientPointer'), shallow);
const Implementation = useXR((xr) => xr.transientPointer);
if (Implementation === false) {
return null;
}
return (_jsx(_Fragment, { children: transientPointerStates.map((state) => {
const ResolvedImpl = resolveInputSourceImplementation(Implementation, state.inputSource.handedness, {});
if (ResolvedImpl === false) {
return null;
}
return (_jsx(xrInputSourceStateContext.Provider, { value: state, children: _jsx(XRSpace, { space: "target-ray-space", children: _jsx(Suspense, { children: typeof ResolvedImpl === 'function' ? (_jsx(ResolvedImpl, {})) : (_jsx(DefaultXRTransientPointer, { ...ResolvedImpl })) }) }) }, objectToKey(state)));
}) }));
}
function XRGazes() {
const gazeStates = useXR((xr) => xr.inputSourceStates.filter((state) => state.type === 'gaze'), shallow);
const Implementation = useXR((xr) => xr.gaze);
if (Implementation === false) {
return null;
}
return (_jsx(_Fragment, { children: gazeStates.map((state) => {
return (_jsx(xrInputSourceStateContext.Provider, { value: state, children: _jsx(XRSpace, { space: "target-ray-space", children: _jsx(Suspense, { children: typeof Implementation === 'function' ? (_jsx(Implementation, {})) : (_jsx(DefaultXRGaze, { ...spreadable(Implementation) })) }) }) }, objectToKey(state)));
}) }));
}
function XRScreenInputs() {
const screenInputStates = useXR((xr) => xr.inputSourceStates.filter((state) => state.type === 'screenInput'), shallow);
const Implementation = useXR((xr) => xr.screenInput);
if (Implementation === false) {
return null;
}
return (_jsx(_Fragment, { children: screenInputStates.map((state) => {
return (_jsx(xrInputSourceStateContext.Provider, { value: state, children: _jsx(XRSpace, { space: "target-ray-space", children: _jsx(Suspense, { children: typeof Implementation === 'function' ? (_jsx(Implementation, {})) : (_jsx(DefaultXRScreenInput, { ...spreadable(Implementation) })) }) }) }, objectToKey(state)));
}) }));
}
function spreadable(value) {
if (value === true) {
return undefined;
}
return value;
}