UNPKG

@react-three/xr

Version:

VR/AR for react-three-fiber

167 lines (166 loc) 7.66 kB
import { GetWorldMatrixFromXRHitTest } from '@pmndrs/xr'; import { RefObject } from 'react'; import { Group, Object3D } from 'three'; export { createXRHitTestSource, requestXRHitTest, type GetWorldMatrixFromXRHitTest } from '@pmndrs/xr'; /** * Hook for creating a hit test source originating from the provided object or XRSpace. The provided object must be statically positioned in the XRSpace. * * @param relativeTo - The XRSpace, XRReferenceSpace, or Object3D to perform hit-tests from * @param trackableType - A string, or array of strings that specify the types of surfaces to hit test against ('point', 'plane', 'mesh') * * @example * function ManualHitTest() { * const meshRef = useRef<Mesh>(null) * const hitTestSource = useXRHitTestSource('viewer') * const [someCondition, setSomeCondition] = useState(false) * const [hitResults, setHitResults] = useState<XRHitTestResult[]>([]) * * useFrame((_, __, frame: XRFrame | undefined) => { * // Only perform hit testing when certain conditions are met * if (frame && hitTestSource && someCondition) { * const results = frame.getHitTestResults(hitTestSource.source) * setHitResults(results) * } * }) * return ( * <IfInSessionMode allow={'immersive-ar'}> * <XRDomOverlay> * <button onClick={() => setSomeCondition(true)}>Turn on hit testing</button> * </XRDomOverlay> * </IfInSessionMode> * ) * } * * @see [Hit Test Tutorial](https://pmndrs.github.io/xr/docs/tutorials/hit-test) * @see [Hit Test Example](https://pmndrs.github.io/xr/examples/hit-testing/) */ export declare function useXRHitTestSource(relativeTo: RefObject<Object3D | null> | XRSpace | XRReferenceSpaceType, trackableType?: XRHitTestTrackableType | Array<XRHitTestTrackableType>): { source: XRHitTestSource; getWorldMatrix: (target: import("three").Matrix4, result: XRHitTestResult) => boolean; } | undefined; /** * Hook for setting up a continous hit test originating from the provided object or XRSpace. The provided object must be statically positioned in the XRSpace. * * @param fn - Callback function that contains the results of the hit test, and a function to retrieve the world matrix * @param relativeTo - The XRSpace, XRReferenceSpace, or Object3D to perform hit-tests from * @param trackableType - A string, or array of strings that specify the types of surfaces to hit test against ('point', 'plane', 'mesh') * * @example * const matrixHelper = new Matrix4() * const hitTestPosition = new Vector3() * * function ContinuousHitTest() { * const previewRef = useRef<Mesh>(null) * * useXRHitTest( * (results, getWorldMatrix) => { * if (results.length === 0) return * * getWorldMatrix(matrixHelper, results[0]) * hitTestPosition.setFromMatrixPosition(matrixHelper) * }, * 'viewer' * ) * * useFrame(() => { * if (hitTestPosition && previewRef.current) { * previewRef.current.position.copy(hitTestPosition) * } * }) * * return ( * <mesh ref={previewRef} position={hitPosition}> * <sphereGeometry args={[0.05]} /> * <meshBasicMaterial color="red" /> * </mesh> * ) * } * * @see [Hit Test Tutorial](https://pmndrs.github.io/xr/docs/tutorials/hit-test) * @see [Hit Test Example](https://pmndrs.github.io/xr/examples/hit-testing/) */ export declare function useXRHitTest(fn: ((results: Array<XRHitTestResult>, getWorldMatrix: GetWorldMatrixFromXRHitTest) => void) | undefined, relativeTo: RefObject<Object3D | null> | XRSpace | XRReferenceSpaceType, trackableType?: XRHitTestTrackableType | Array<XRHitTestTrackableType>): void; /** * Hook that returns a function to request a single hit test. Cannot be called in the useFrame hook. * * @example * const matrixHelper = new Matrix4() * function EventDrivenHitTest() { * const requestHitTest = useXRRequestHitTest() * const [placedObjects, setPlacedObjects] = useState<Vector3[]>([]) * * const handleTap = async () => { * const hitTestResult = await requestHitTest('viewer', ['plane', 'mesh']) * const { results, getWorldMatrix } = hitTestResult * if (results?.length > 0) { * getWorldMatrix(matrixHelper, results[0]) * const position = new Vector3().setFromMatrixPosition(matrixHelper) * setPlacedObjects((prev) => [...prev, position]) * } * } * * return ( * <> * <IfInSessionMode allow={'immersive-ar'}> * <XRDomOverlay> * <button onClick={handleTap}>Place Object</button> * </XRDomOverlay> * </IfInSessionMode> * * {placedObjects.map((position, index) => ( * <mesh key={index} position={position}> * <sphereGeometry args={[0.1]} /> * <meshBasicMaterial color="blue" /> * </mesh> * ))} * </> * ) * } * * @see [Hit Test Tutorial](https://pmndrs.github.io/xr/docs/tutorials/hit-test) * @see [Hit Test Example](https://pmndrs.github.io/xr/examples/hit-testing/) */ export declare function useXRRequestHitTest(): (relativeTo: RefObject<Object3D | null> | XRSpace | XRReferenceSpaceType, trackableType?: XRHitTestTrackableType | Array<XRHitTestTrackableType>) => Promise<{ results: XRHitTestResult[]; getWorldMatrix: (target: import("three").Matrix4, result: XRHitTestResult) => boolean; } | undefined> | undefined; /** * A convenience wrapper component for the useXRHitTest hook. Used to setup hit testing in the scene. * * @param props * #### `space` - [XRSpaceType](https://developer.mozilla.org/en-US/docs/Web/API/XRSpace) | [XRReferenceSpaceType](https://developer.mozilla.org/en-US/docs/Web/API/XRReferenceSpace#reference_space_types) * #### `onResults` - Callback function that is called with the results of the hit test * * @example * const matrixHelper = new Matrix4() * const hitTestPosition = new Vector3() * * const store = createXRStore({ * hand: () => { * const inputSourceState = useXRInputSourceStateContext() * * return ( * <> * <DefaultXRHand /> * <XRHitTest * space={inputSourceState.inputSource.targetRaySpace} * onResults={(results, getWorldMatrix) => { * if (results.length === 0) return * getWorldMatrix(matrixHelper, results[0]) * hitTestPosition.setFromMatrixPosition(matrixHelper) * }} * /> * </> * ) * }, * }) * * @see [Hit Test Tutorial](https://pmndrs.github.io/xr/docs/tutorials/hit-test) * @see [Hit Test Example](https://pmndrs.github.io/xr/examples/hit-testing/) * @function */ export declare const XRHitTest: import("react").ForwardRefExoticComponent<Omit<Omit<import("@react-three/fiber/dist/declarations/src/core/utils.js").Mutable<import("@react-three/fiber/dist/declarations/src/core/utils.js").Overwrite<Partial<import("@react-three/fiber/dist/declarations/src/core/utils.js").Overwrite<Group<import("three").Object3DEventMap>, import("@react-three/fiber").MathProps<Group<import("three").Object3DEventMap>> & import("@react-three/fiber").ReactProps<Group<import("three").Object3DEventMap>> & Partial<import("@react-three/fiber").EventHandlers>>>, Omit<import("@react-three/fiber").InstanceProps<Group<import("three").Object3DEventMap>, typeof Group>, "object">>>, "children"> & { space?: XRSpace | XRReferenceSpaceType; trackableType?: XRHitTestTrackableType | Array<XRHitTestTrackableType>; onResults?: (results: Array<XRHitTestResult>, getWorldMatrix: GetWorldMatrixFromXRHitTest) => void; }, "ref"> & import("react").RefAttributes<Group<import("three").Object3DEventMap>>>;