Skip to content

Commit

Permalink
support <XRSpace space="grib-space" /> and more
Browse files Browse the repository at this point in the history
  • Loading branch information
bbohlender committed Nov 1, 2024
1 parent d682279 commit 432aff6
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 5 deletions.
5 changes: 3 additions & 2 deletions packages/react/xr/src/hand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,19 @@ export const XRHandModel = forwardRef<Object3D, XRHandModelOptions>((options, re
})

/**
* @deprecated use `<XRSpace space="wrist">` instead of `<XRHandJoint joint="wrist">`
* component for placing content in the hand anchored at a specific joint such as the index finger tip
*
* properties
* - `joint` is the name of the joint (e.g. `"wrist"`)
*
* the component allows children to be placed inside for e.g. visualizing a tooltip over the index finger tip
*
*/
export const XRHandJoint = forwardRef<Object3D, { joint: XRHandJoint; children?: ReactNode }>(
({ joint, children }, ref) => {
const state = useXRInputSourceStateContext('hand')
return (
<XRSpace ref={ref} space={state.inputSource.hand.get(joint)!}>
<XRSpace ref={ref} space={joint}>
{children}
</XRSpace>
)
Expand Down
51 changes: 48 additions & 3 deletions packages/react/xr/src/space.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,22 @@ import {
import { Group, Object3D } from 'three'
import { xrSpaceContext } from './contexts.js'
import { useXR } from './xr.js'
import { useXRControllerButtonEvent } from './controller.js'
import { useXRInputSourceStateContext } from './input.js'

/**
* component that puts its children at the provided space (or reference space type)
*/
export const XRSpace = forwardRef<
Object3D,
{
space: XRSpace | XRReferenceSpaceType
space: XRSpace | XRSpaceType
children?: ReactNode
}
>(({ space, children }, ref) => {
const internalRef = useRef<Group | null>(null)
// eslint-disable-next-line react-hooks/rules-of-hooks
const resolvedSpace = typeof space === 'string' ? useXRSpace(space) : space
const resolvedSpace = useXRSpace(space as any)
useImperativeHandle(ref, () => internalRef.current!, [])
useApplyXRSpaceMatrix(internalRef, resolvedSpace)
const setRef = useCallback((group: Group | null) => {
Expand All @@ -44,14 +46,57 @@ export const XRSpace = forwardRef<
)
})

export type XRSpaceType = XRReferenceSpaceType | XRInputSourceSpaceType | XRHandJointSpaceType

export type XRInputSourceSpaceType = 'grip-space' | 'target-ray-space'

export type XRHandJointSpaceType = XRHandJoint

/**
* hook for retrieving getting xr space from the context
*/
export function useXRSpace(): XRSpace

export function useXRSpace(type: XRInputSourceSpaceType | XRHandJointSpaceType): XRSpace | undefined

export function useXRSpace(type: XRReferenceSpaceType): XRReferenceSpace | undefined

export function useXRSpace(type?: XRReferenceSpaceType): XRSpace | XRReferenceSpace | undefined {
export function useXRSpace(type?: XRSpaceType): XRSpace | XRReferenceSpace | undefined {
switch (type) {
case 'grip-space':
// eslint-disable-next-line react-hooks/rules-of-hooks
return useXRInputSourceStateContext().inputSource.gripSpace
case 'target-ray-space':
// eslint-disable-next-line react-hooks/rules-of-hooks
return useXRInputSourceStateContext().inputSource.targetRaySpace
case 'wrist':
case 'thumb-metacarpal':
case 'thumb-phalanx-proximal':
case 'thumb-phalanx-distal':
case 'thumb-tip':
case 'index-finger-metacarpal':
case 'index-finger-phalanx-proximal':
case 'index-finger-phalanx-intermediate':
case 'index-finger-phalanx-distal':
case 'index-finger-tip':
case 'middle-finger-metacarpal':
case 'middle-finger-phalanx-proximal':
case 'middle-finger-phalanx-intermediate':
case 'middle-finger-phalanx-distal':
case 'middle-finger-tip':
case 'ring-finger-metacarpal':
case 'ring-finger-phalanx-proximal':
case 'ring-finger-phalanx-intermediate':
case 'ring-finger-phalanx-distal':
case 'ring-finger-tip':
case 'pinky-finger-metacarpal':
case 'pinky-finger-phalanx-proximal':
case 'pinky-finger-phalanx-intermediate':
case 'pinky-finger-phalanx-distal':
case 'pinky-finger-tip':
// eslint-disable-next-line react-hooks/rules-of-hooks
return useXRInputSourceStateContext('hand').inputSource.hand.get(type)
}
if (type == null) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const context = useContext(xrSpaceContext)
Expand Down

0 comments on commit 432aff6

Please sign in to comment.