@react-three/xr
Version:
VR/AR for react-three-fiber
42 lines (41 loc) • 1.87 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { isXRInputSourceState } from '@pmndrs/xr/internals';
import { useFrame } from '@react-three/fiber';
import { forwardRef, useImperativeHandle, useMemo, useRef } from 'react';
import { Matrix4 } from 'three';
import { Interactive } from './interactive.js';
/**
* @deprecated use `DragControls` instead
*/
export const RayGrab = forwardRef(function RayGrab({ onSelectStart, onSelectEnd, children, ...rest }, forwardedRef) {
const grabbingController = useRef(undefined);
const groupRef = useRef(null);
const previousTransform = useMemo(() => new Matrix4(), []);
useImperativeHandle(forwardedRef, () => groupRef.current);
useFrame(() => {
const controller = grabbingController.current;
const group = groupRef.current;
if (!group || !controller)
return;
group.applyMatrix4(previousTransform);
controller.updateWorldMatrix(true, false);
group.applyMatrix4(controller.matrixWorld);
group.updateMatrixWorld();
previousTransform.copy(controller.matrixWorld).invert();
});
return (_jsx(Interactive, { ref: groupRef, onSelectStart: (e) => {
if (isXRInputSourceState(e.target) &&
(e.target.type === 'controller' || e.target.type === 'hand') &&
e.target.object != null) {
grabbingController.current = e.target.object;
e.target.object.updateWorldMatrix(true, false);
previousTransform.copy(e.target.object.matrixWorld).invert();
onSelectStart?.(e);
}
}, onSelectEnd: (e) => {
if (e.target.controller === grabbingController.current) {
grabbingController.current = undefined;
}
onSelectEnd?.(e);
}, ...rest, children: children }));
});