react-xr
react-xr copied to clipboard
[Question] Great Library ! How to intercept Motion data
I tried a few examples and they seemed to work very well. This one I'm a bit stumped :thinking: It seems very simple - I'm just trying to intercept the position and orientation of a Quest 2 headset and left/right controllers.
import React, { useEffect } from 'react';
import { Canvas, useFrame, useThree } from '@react-three/fiber';
import { useController } from '@react-three/xr';
const WebXr = () => {
const { gl } = useThree();
const leftController = useController('left');
const rightController = useController('right');
const gazeController = useController('gaze');
useEffect(() => {
const handleControllerInput = (event) => {
console.log(event.target.name, event.target.position.toArray(), event.target.rotation.toArray());
};
leftController.addEventListener('selectstart', handleControllerInput);
rightController.addEventListener('selectstart', handleControllerInput);
gazeController.addEventListener('selectstart', handleControllerInput);
return () => {
leftController.removeEventListener('selectstart', handleControllerInput);
rightController.removeEventListener('selectstart', handleControllerInput);
gazeController.removeEventListener('selectstart', handleControllerInput);
};
}, [leftController, rightController, gazeController]);
useFrame(() => {
gl.xr.isPresenting && console.log(leftController.position.toArray(), rightController.position.toArray(), gazeController.position.toArray());
});
return (
<Canvas>
<mesh position={[0, 0, -3]}>
<boxBufferGeometry args={[2, 2, 2]} />
<meshBasicMaterial color="white" />
</mesh>
</Canvas>
);
};
export default WebXr;
It seems to transpile fine, but in the console I'm getting ...
It's all being used in Canvas no?
Or, am I thinking about this wrong - do I need references in other sub components?
Is there a simple example which prints the data I'm looking for to console, it seems to have eluded me...
Any help is most appreciated :)
Your WebXR
component itself relies on R3F hooks which can only be called within a component wrapped in <Canvas />
since it relies on context for hooks.
import React, { useEffect } from 'react';
import { Canvas, useFrame, useThree } from '@react-three/fiber';
import { useController } from '@react-three/xr';
const WebXr = () => {
const { gl } = useThree();
const leftController = useController('left');
const rightController = useController('right');
const gazeController = useController('gaze');
useEffect(() => {
const handleControllerInput = (event) => {
console.log(event.target.name, event.target.position.toArray(), event.target.rotation.toArray());
};
leftController.addEventListener('selectstart', handleControllerInput);
rightController.addEventListener('selectstart', handleControllerInput);
gazeController.addEventListener('selectstart', handleControllerInput);
return () => {
leftController.removeEventListener('selectstart', handleControllerInput);
rightController.removeEventListener('selectstart', handleControllerInput);
gazeController.removeEventListener('selectstart', handleControllerInput);
};
}, [leftController, rightController, gazeController]);
useFrame(() => {
gl.xr.isPresenting && console.log(leftController.position.toArray(), rightController.position.toArray(), gazeController.position.toArray());
});
return (
<mesh position={[0, 0, -3]}>
<boxBufferGeometry args={[2, 2, 2]} />
<meshBasicMaterial color="white" />
</mesh>
);
};
export default () => (
<Canvas>
<WebXr/>
</Canvas>
);
I think I understand and appreciate what you tried to do with the default export ... but it gives the same error ...
Might there be a working example which does the same thing ? Maybe just for the headset ?
I'd see our examples:
https://github.com/pmndrs/react-xr/blob/be180552145d4aa0e73b7e8fe29258639bf5dc08/examples/src/App.tsx#L1-L61
Closed due to inactivity. If new questions arise in relation to react-three/xr v6, feel free to reopen.