Browse Source

WebXR Hands: address review comments

Rik Cabanier 4 years ago
parent
commit
1d3f443794

+ 43 - 2
examples/jsm/webxr/XRHandOculusMeshModel.js

@@ -55,11 +55,49 @@ class XRHandOculusMeshModel {
 				'b_%_pinky3', // XRHand.LITTLE_PHALANX_DISTAL,
 				'b_%_pinkynull', // XRHand.LITTLE_PHALANX_TIP
 			];
+
+			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',
+			];
+
+			let i = 0;
+
 			bonesMapping.forEach( boneName => {
 
 				if ( boneName ) {
 
 					const bone = object.getObjectByName( boneName.replace( /%/g, handedness === 'right' ? 'r' : 'l' ) );
+
+					if ( bone !== undefined) {
+
+						bone.jointName = joints [ i ];
+
+					}
+
 					this.bones.push( bone );
 
 				} else {
@@ -68,6 +106,8 @@ class XRHandOculusMeshModel {
 
 				}
 
+				i ++;
+
 			} );
 
 		} );
@@ -81,9 +121,10 @@ class XRHandOculusMeshModel {
 		for ( let i = 0; i < this.bones.length; i ++ ) {
 
 			const bone = this.bones[ i ];
-			const XRJoint = XRJoints[ i ];
 
-			if ( XRJoint ) {
+			if ( bone ) {
+
+				const XRJoint = XRJoints[ bone.jointName ];
 
 				if ( XRJoint.visible ) {
 

+ 31 - 9
examples/jsm/webxr/XRHandPrimitiveModel.js

@@ -35,18 +35,40 @@ class XRHandPrimitiveModel {
 			const jointMaterial = new MeshStandardMaterial( { color: 0xffffff, roughness: 1, metalness: 0 } );
 			const tipMaterial = new MeshStandardMaterial( { color: 0x999999, roughness: 1, metalness: 0 } );
 
-			const tipIndexes = [
-				4,
-				9,
-				14,
-				19,
-				24,
+			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 ( let i = 0; i <= 24; i ++ ) {
 
-				var cube = new Mesh( geometry, tipIndexes.indexOf( i ) !== - 1 ? tipMaterial : jointMaterial );
+			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 );
 
 			}
@@ -66,7 +88,7 @@ class XRHandPrimitiveModel {
 		for ( let i = 0; i < objects.length; i ++ ) {
 
 			const jointMesh = objects[ i ];
-			const XRJoint = XRJoints[ i ];
+			const XRJoint = XRJoints[ jointMesh.jointName ];
 
 			if ( XRJoint.visible ) {
 

+ 6 - 6
examples/webxr_vr_handinput_cubes.html

@@ -160,7 +160,7 @@
 
 				if ( grabbing ) {
 
-					const indexTip = controller.joints[ 9 ];
+					const indexTip = controller.joints[ 'index-finger-tip' ];
 					const sphere = collideObject( indexTip );
 
 					if ( sphere ) {
@@ -172,7 +172,7 @@
 							scaling.active = true;
 							scaling.object = sphere;
 							scaling.initialScale = sphere.scale.x;
-							scaling.initialDistance = indexTip.position.distanceTo( hand2.joints[ 9 ].position );
+							scaling.initialDistance = indexTip.position.distanceTo( hand2.joints[ 'index-finger-tip' ].position );
 							return;
 
 						}
@@ -190,7 +190,7 @@
 				const spawn = new THREE.Mesh( geometry, material );
 				spawn.geometry.computeBoundingSphere();
 
-				const indexTip = controller.joints[ 9 ];
+				const indexTip = controller.joints[ 'index-finger-tip' ];
 				spawn.position.copy( indexTip.position );
 				spawn.quaternion.copy( indexTip.quaternion );
 
@@ -222,7 +222,7 @@
 			function onPinchStartRight( event ) {
 
 				const controller = event.target;
-				const indexTip = controller.joints[ 9 ];
+				const indexTip = controller.joints[ 'index-finger-tip' ];
 				const object = collideObject( indexTip );
 				if ( object ) {
 
@@ -266,8 +266,8 @@
 
 				if ( scaling.active ) {
 
-					const indexTip1Pos = hand1.joints[ 9 ].position;
-					const indexTip2Pos = hand2.joints[ 9 ].position;
+					const indexTip1Pos = hand1.joints[ 'index-finger-tip' ].position;
+					const indexTip2Pos = hand2.joints[ 'index-finger-tip' ].position;
 					const distance = indexTip1Pos.distanceTo( indexTip2Pos );
 					const newScale = scaling.initialScale + distance / scaling.initialDistance - 1;
 					scaling.object.scale.setScalar( newScale );

+ 37 - 41
src/renderers/webxr/WebXRController.js

@@ -20,25 +20,9 @@ Object.assign( WebXRController.prototype, {
 			this._hand.matrixAutoUpdate = false;
 			this._hand.visible = false;
 
-			this._hand.joints = [];
+			this._hand.joints = {};
 			this._hand.inputState = { pinching: false };
 
-			if ( window.XRHand ) {
-
-				for ( let i = 0; i <= 24; i ++ ) {
-
-					// The transform of this joint will be updated with the joint pose on each frame
-					const joint = new Group();
-					joint.matrixAutoUpdate = false;
-					joint.visible = false;
-					this._hand.joints.push( joint );
-					// ??
-					this._hand.add( joint );
-
-				}
-
-			}
-
 		}
 
 		return this._hand;
@@ -138,13 +122,25 @@ Object.assign( WebXRController.prototype, {
 			if ( hand && inputSource.hand ) {
 
 				handPose = true;
-				let i = 0;
 
 				for ( const inputjoint of inputSource.hand.values() ) {
 
 					// Update the joints groups with the XRJoint poses
 					const jointPose = frame.getJointPose( inputjoint, referenceSpace );
-					const joint = hand.joints[ i ++ ];
+
+					if ( hand.joints[ inputjoint.jointName ] === undefined ) {
+
+						// The transform of this joint will be updated with the joint pose on each frame
+						const joint = new Group();
+						joint.matrixAutoUpdate = false;
+						joint.visible = false;
+						hand.joints[ inputjoint.jointName ] = joint;
+						// ??
+						hand.add( joint );
+
+					}
+
+					const joint = hand.joints[ inputjoint.jointName ];
 
 					if ( jointPose !== null ) {
 
@@ -156,35 +152,35 @@ Object.assign( WebXRController.prototype, {
 
 					joint.visible = jointPose !== null;
 
-					// Custom events
+				}
 
-					// Check pinchz
-					const indexTip = hand.joints[ 9 ];
-					const thumbTip = hand.joints[ 4 ];
-					const distance = indexTip.position.distanceTo( thumbTip.position );
+				// Custom events
 
-					const distanceToPinch = 0.02;
-					const threshold = 0.005;
+				// Check pinchz
+				const indexTip = hand.joints[ 'index-finger-tip' ];
+				const thumbTip = hand.joints[ 'thumb-tip' ];
+				const distance = indexTip.position.distanceTo( thumbTip.position );
 
-					if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
+				const distanceToPinch = 0.02;
+				const threshold = 0.005;
 
-						hand.inputState.pinching = false;
-						this.dispatchEvent( {
-							type: 'pinchend',
-							handedness: inputSource.handedness,
-							target: this
-						} );
+				if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) {
 
-					} else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
+					hand.inputState.pinching = false;
+					this.dispatchEvent( {
+						type: 'pinchend',
+						handedness: inputSource.handedness,
+						target: this
+					} );
 
-						hand.inputState.pinching = true;
-						this.dispatchEvent( {
-							type: 'pinchstart',
-							handedness: inputSource.handedness,
-							target: this
-						} );
+				} else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) {
 
-					}
+					hand.inputState.pinching = true;
+					this.dispatchEvent( {
+						type: 'pinchstart',
+						handedness: inputSource.handedness,
+						target: this
+					} );
 
 				}