소스 검색

Use Instanced Meshes in XRHandPrimitiveModel.js (#21702)

Johnathon Selstad 4 년 전
부모
커밋
ea2e0f07b5
1개의 변경된 파일56개의 추가작업 그리고 64개의 파일을 삭제
  1. 56 64
      examples/jsm/webxr/XRHandPrimitiveModel.js

+ 56 - 64
examples/jsm/webxr/XRHandPrimitiveModel.js

@@ -2,8 +2,9 @@ import {
 	SphereGeometry,
 	BoxGeometry,
 	MeshStandardMaterial,
-	Mesh,
-	Group
+	InstancedMesh,
+	Matrix4,
+	Vector3
 } from '../../../build/three.module.js';
 
 class XRHandPrimitiveModel {
@@ -12,93 +13,84 @@ class XRHandPrimitiveModel {
 
 		this.controller = controller;
 		this.handModel = handModel;
+		this.envMap = null;
 
-	  this.envMap = null;
+		let geometry;
+		const jointMaterial = new MeshStandardMaterial( { color: 0xffffff, roughness: 1, metalness: 0 } );
 
-		this.handMesh = new Group();
-		this.handModel.add( this.handMesh );
-
-		if ( window.XRHand ) {
-
-			let geometry;
-
-			if ( ! options || ! options.primitive || options.primitive === 'sphere' ) {
+		if ( ! options || ! options.primitive || options.primitive === 'sphere' ) {
 
-				geometry = new SphereGeometry( 1, 10, 10 );
+			geometry = new SphereGeometry( 1, 10, 10 );
 
-			} else if ( options.primitive === 'box' ) {
+		} else if ( options.primitive === 'box' ) {
 
-				geometry = new BoxGeometry( 1, 1, 1 );
+			geometry = new BoxGeometry( 1, 1, 1 );
 
-			}
-
-			const jointMaterial = new MeshStandardMaterial( { color: 0xffffff, roughness: 1, metalness: 0 } );
-			const tipMaterial = new MeshStandardMaterial( { color: 0x999999, roughness: 1, metalness: 0 } );
-
-			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'
-			];
-
-			for ( const jointName of joints ) {
-
-				var cube = new Mesh( geometry, jointName.indexOf( 'tip' ) !== - 1 ? tipMaterial : jointMaterial );
-				cube.castShadow = true;
-				cube.receiveShadow = true;
-				cube.jointName = jointName;
-				this.handMesh.add( cube );
+		}
 
-			}
+		this.handMesh = new InstancedMesh( geometry, jointMaterial, 30 );
+		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'
+		];
+
+		this.tempMat = new Matrix4(); this.tempVec = new Vector3( 1, 1, 1 );
 
 	}
 
 	updateMesh() {
 
 		const defaultRadius = 0.008;
-		const objects = this.handMesh.children;
 
 		// XR Joints
 		const XRJoints = this.controller.joints;
+		let count = 0;
 
-		for ( let i = 0; i < objects.length; i ++ ) {
+		for ( let i = 0; i < this.joints.length; i ++ ) {
 
-			const jointMesh = objects[ i ];
-			const XRJoint = XRJoints[ jointMesh.jointName ];
+			const XRJoint = XRJoints[ this.joints[ i ] ];
 
 			if ( XRJoint.visible ) {
 
-				jointMesh.position.copy( XRJoint.position );
-				jointMesh.quaternion.copy( XRJoint.quaternion );
-				jointMesh.scale.setScalar( XRJoint.jointRadius || defaultRadius );
+				this.handMesh.setMatrixAt( i, this.tempMat.compose( XRJoint.position, XRJoint.quaternion,
+					this.tempVec.set( 1, 1, 1 ).multiplyScalar( XRJoint.jointRadius || defaultRadius ) ) );
+				count ++;
 
 			}
 
-			jointMesh.visible = XRJoint.visible;
+		}
+
+		this.handMesh.count = count;
+		if ( this.handMesh.instanceMatrix ) {
+
+			this.handMesh.instanceMatrix.needsUpdate = true;
 
 		}