UNPKG

@react-three/xr

Version:

VR/AR for react-three-fiber

95 lines (94 loc) 5.7 kB
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; }