Spaces:
Running
Running
import { GLTFLoader } from '../loaders/GLTFLoader.js'; | |
const DEFAULT_HAND_PROFILE_PATH = 'https://cdn.jsdelivr.net/npm/@webxr-input-profiles/[email protected]/dist/profiles/generic-hand/'; | |
class XRHandMeshModel { | |
constructor( handModel, controller, path, handedness, loader = null, onLoad = null ) { | |
this.controller = controller; | |
this.handModel = handModel; | |
this.bones = []; | |
if ( loader === null ) { | |
loader = new GLTFLoader(); | |
loader.setPath( path || DEFAULT_HAND_PROFILE_PATH ); | |
} | |
loader.load( `${handedness}.glb`, gltf => { | |
const object = gltf.scene.children[ 0 ]; | |
this.handModel.add( object ); | |
const mesh = object.getObjectByProperty( 'type', 'SkinnedMesh' ); | |
mesh.frustumCulled = false; | |
mesh.castShadow = true; | |
mesh.receiveShadow = true; | |
const joints = [ | |
'wrist', | |
'thumb-metacarpal', | |
'thumb-phalanx-proximal', | |
'thumb-phalanx-distal', | |
'thumb-tip', | |
'index-finger-metacarpal', | |
'index-finger-phalanx-proximal', | |
'index-finger-phalanx-intermediate', | |
'index-finger-phalanx-distal', | |
'index-finger-tip', | |
'middle-finger-metacarpal', | |
'middle-finger-phalanx-proximal', | |
'middle-finger-phalanx-intermediate', | |
'middle-finger-phalanx-distal', | |
'middle-finger-tip', | |
'ring-finger-metacarpal', | |
'ring-finger-phalanx-proximal', | |
'ring-finger-phalanx-intermediate', | |
'ring-finger-phalanx-distal', | |
'ring-finger-tip', | |
'pinky-finger-metacarpal', | |
'pinky-finger-phalanx-proximal', | |
'pinky-finger-phalanx-intermediate', | |
'pinky-finger-phalanx-distal', | |
'pinky-finger-tip', | |
]; | |
joints.forEach( jointName => { | |
const bone = object.getObjectByName( jointName ); | |
if ( bone !== undefined ) { | |
bone.jointName = jointName; | |
} else { | |
console.warn( `Couldn't find ${jointName} in ${handedness} hand mesh` ); | |
} | |
this.bones.push( bone ); | |
} ); | |
if ( onLoad ) onLoad( object ); | |
} ); | |
} | |
updateMesh() { | |
// XR Joints | |
const XRJoints = this.controller.joints; | |
for ( let i = 0; i < this.bones.length; i ++ ) { | |
const bone = this.bones[ i ]; | |
if ( bone ) { | |
const XRJoint = XRJoints[ bone.jointName ]; | |
if ( XRJoint.visible ) { | |
const position = XRJoint.position; | |
bone.position.copy( position ); | |
bone.quaternion.copy( XRJoint.quaternion ); | |
// bone.scale.setScalar( XRJoint.jointRadius || defaultRadius ); | |
} | |
} | |
} | |
} | |
} | |
export { XRHandMeshModel }; | |