Skip to content

Instantly share code, notes, and snippets.

@micmania1
Created January 13, 2022 09:40
Show Gist options
  • Save micmania1/9ae93de568626cd3c40868473ef5ca48 to your computer and use it in GitHub Desktop.
Save micmania1/9ae93de568626cd3c40868473ef5ca48 to your computer and use it in GitHub Desktop.
XR Controls ideas
import { MotionController } from '@webxr-input-profiles/motion-controllers'
import { useEffect, useState } from 'react'
import { Group, Object3D, Vector3, XRHand } from 'three'
import { XRControllerModelFactory } from 'webxr/XRControllerModelFactory'
import { useXR } from '../XR'
const modelFactory = new XRControllerModelFactory()
const modelCache = new WeakMap<Group, any>()
export const useMotionControllers = () => {
const { controllers } = useXR()
const [motionControllers, setMotionControllers] = useState<MotionController[]>([])
useEffect(() => {
const mControllers: MotionController[] = []
controllers.forEach(({ controller }) => {
// Attach 3D model of the controller
let model: Object3D
if (modelCache.has(controller)) {
model = modelCache.get(controller)
} else {
model = modelFactory.createControllerModel(controller) as any
modelCache.set(controller, model)
}
mControllers.push((model as any).motionController)
})
setMotionControllers(mControllers)
return () => {
setMotionControllers([])
}
}, [controllers])
return motionControllers
}
export const useMotionController = (hand: XRHand) => {
const motionControllers = useMotionControllers()
return motionControllers.find((c) => (c.xrInputSource as any).handedness === hand) ?? null
}
export const useJoystick = (hand: XRHand): Vector3 | null => {
const motionController = useMotionController(hand)
if (motionController) {
return new Vector3(0, 0, 0)
}
return null
}
export const useTouchpad = (hand: XRHand) => {
const motionController = useMotionController(hand)
if (motionController) {
return new Vector3(0, 0, 0)
}
return null
}
export const useMovementControls = (hand: XRHand, preferredControl: 'joystick' | 'touchpad' = 'joystick') => {
const joystick = useJoystick(hand)
const touchpad = useTouchpad(hand)
if (joystick === null) {
return touchpad
}
if (touchpad === null) {
return joystick
}
return preferredControl === 'joystick' ? joystick : touchpad
}
export const useButton = (button: string, hand: XRHand) => {
const motionController = useMotionController(hand)
if (motionController) {
if (Object.keys(motionController.components).find((name) => name === button)) {
return motionController.components[button]
}
}
return null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment