Skip to content

Commit

Permalink
Add useXRFrame
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Rutzer authored and sniok committed Mar 21, 2021
1 parent f3b96d5 commit 74b926b
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,16 @@ interface XRController {
`inputSource` is the WebXR input source [(MDN)](https://developer.mozilla.org/en-US/docs/Web/API/XRInputSource). Note that it will not be available before controller is connected.
## `useXRFrame`
Accepts a callback which will be invoked in the animation loop of an active XR session.
[(MDN)](https://developer.mozilla.org/en-US/docs/Web/API/XRSession/requestAnimationFrame)
```jsx
useXRFrame((time, xrFrame) => {
// do something on each frame of an active XR session
})
```
## `useController`
Use this hook to get an instance of the controller
Expand Down
27 changes: 27 additions & 0 deletions src/XR.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,33 @@ export const useXR = () => {
return contextValue
}

export const useXRFrame = (callback: (time: DOMHighResTimeStamp, xrFrame: XRFrame) => void) => {
const { gl } = useThree()
const requestRef = React.useRef()
const previousTimeRef = React.useRef()

const loop = React.useCallback((time: DOMHighResTimeStamp, xrFrame: XRFrame) => {
if (previousTimeRef.current !== undefined) {
callback(time, xrFrame)
}

previousTimeRef.current = time
requestRef.current = gl.xr.getSession().requestAnimationFrame(loop)
}, [gl.xr, callback])

React.useEffect(() => {
if (!gl.xr?.isPresenting && !requestRef.current) {
return
}

requestRef.current = gl.xr.getSession().requestAnimationFrame(loop)

return () => {
gl.xr.getSession().cancelAnimationFrame(loop)
}
}, [gl, gl.xr.isPresenting, loop])
}

export const useController = (handedness: XRHandedness) => {
const { controllers } = useXR()
const controller = React.useMemo(() => controllers.find((it) => it.inputSource.handedness === handedness), [handedness, controllers])
Expand Down

0 comments on commit 74b926b

Please sign in to comment.