104 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
		
		
			
		
	
	
			104 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| 
								 | 
							
								import {
							 | 
						||
| 
								 | 
							
									DynamicDrawUsage,
							 | 
						||
| 
								 | 
							
									SphereGeometry,
							 | 
						||
| 
								 | 
							
									BoxGeometry,
							 | 
						||
| 
								 | 
							
									MeshStandardMaterial,
							 | 
						||
| 
								 | 
							
									InstancedMesh,
							 | 
						||
| 
								 | 
							
									Matrix4,
							 | 
						||
| 
								 | 
							
									Vector3
							 | 
						||
| 
								 | 
							
								} from 'three';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const _matrix = new Matrix4();
							 | 
						||
| 
								 | 
							
								const _vector = new Vector3();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class XRHandPrimitiveModel {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									constructor( handModel, controller, path, handedness, options ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.controller = controller;
							 | 
						||
| 
								 | 
							
										this.handModel = handModel;
							 | 
						||
| 
								 | 
							
										this.envMap = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let geometry;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if ( ! options || ! options.primitive || options.primitive === 'sphere' ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											geometry = new SphereGeometry( 1, 10, 10 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										} else if ( options.primitive === 'box' ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											geometry = new BoxGeometry( 1, 1, 1 );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const material = new MeshStandardMaterial();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.handMesh = new InstancedMesh( geometry, material, 30 );
							 | 
						||
| 
								 | 
							
										this.handMesh.frustumCulled = false;
							 | 
						||
| 
								 | 
							
										this.handMesh.instanceMatrix.setUsage( DynamicDrawUsage ); // will be updated every frame
							 | 
						||
| 
								 | 
							
										this.handMesh.castShadow = true;
							 | 
						||
| 
								 | 
							
										this.handMesh.receiveShadow = true;
							 | 
						||
| 
								 | 
							
										this.handModel.add( this.handMesh );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.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'
							 | 
						||
| 
								 | 
							
										];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									updateMesh() {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										const defaultRadius = 0.008;
							 | 
						||
| 
								 | 
							
										const joints = this.controller.joints;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										let count = 0;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										for ( let i = 0; i < this.joints.length; i ++ ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											const joint = joints[ this.joints[ i ] ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											if ( joint.visible ) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												_vector.setScalar( joint.jointRadius || defaultRadius );
							 | 
						||
| 
								 | 
							
												_matrix.compose( joint.position, joint.quaternion, _vector );
							 | 
						||
| 
								 | 
							
												this.handMesh.setMatrixAt( i, _matrix );
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
												count ++;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										this.handMesh.count = count;
							 | 
						||
| 
								 | 
							
										this.handMesh.instanceMatrix.needsUpdate = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export { XRHandPrimitiveModel };
							 |