1- /* global THREE, XRRigidTransform */
1+ /* global THREE */
22var registerComponent = require ( '../core/component' ) . registerComponent ;
33var bind = require ( '../utils/bind' ) ;
44
@@ -36,6 +36,9 @@ var JOINTS = [
3636 'pinky-finger-tip'
3737] ;
3838
39+ var THUMB_TIP_INDEX = 4 ;
40+ var INDEX_TIP_INDEX = 9 ;
41+
3942var PINCH_START_DISTANCE = 0.015 ;
4043var PINCH_END_DISTANCE = 0.03 ;
4144var PINCH_POSITION_INTERPOLATION = 0.5 ;
@@ -82,6 +85,10 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
8285 this . pinchEventDetail = { position : new THREE . Vector3 ( ) } ;
8386 this . indexTipPosition = new THREE . Vector3 ( ) ;
8487
88+ this . hasPoses = false ;
89+ this . jointPoses = new Float32Array ( 16 * JOINTS . length ) ;
90+ this . jointRadii = new Float32Array ( JOINTS . length ) ;
91+
8592 this . bindMethods ( ) ;
8693
8794 this . updateReferenceSpace = this . updateReferenceSpace . bind ( this ) ;
@@ -96,7 +103,7 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
96103 if ( ! xrSession ) { return ; }
97104 var referenceSpaceType = self . el . sceneEl . systems . webxr . sessionReferenceSpaceType ;
98105 xrSession . requestReferenceSpace ( referenceSpaceType ) . then ( function ( referenceSpace ) {
99- self . referenceSpace = referenceSpace . getOffsetReferenceSpace ( new XRRigidTransform ( { x : 0 , y : 1.5 , z : 0 } ) ) ;
106+ self . referenceSpace = referenceSpace ;
100107 } ) . catch ( function ( error ) {
101108 self . el . sceneEl . systems . webxr . warnIfFeatureNotRequested ( referenceSpaceType , 'tracked-controls-webxr uses reference space ' + referenceSpaceType ) ;
102109 throw error ;
@@ -121,11 +128,17 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
121128 var controller = this . el . components [ 'tracked-controls' ] && this . el . components [ 'tracked-controls' ] . controller ;
122129 var frame = sceneEl . frame ;
123130 var trackedControlsWebXR = this . el . components [ 'tracked-controls-webxr' ] ;
124- if ( ! controller || ! frame || ! trackedControlsWebXR ) { return ; }
131+ var referenceSpace = this . referenceSpace ;
132+ if ( ! controller || ! frame || ! referenceSpace || ! trackedControlsWebXR ) { return ; }
133+ this . hasPoses = false ;
125134 if ( controller . hand ) {
126135 this . el . object3D . position . set ( 0 , 0 , 0 ) ;
127136 this . el . object3D . rotation . set ( 0 , 0 , 0 ) ;
128- if ( frame . getJointPose ) { this . updateHandModel ( ) ; }
137+
138+ this . hasPoses = frame . fillPoses ( controller . hand . values ( ) , referenceSpace , this . jointPoses ) &&
139+ frame . fillJointRadii ( controller . hand . values ( ) , this . jointRadii ) ;
140+
141+ this . updateHandModel ( ) ;
129142 this . detectGesture ( ) ;
130143 }
131144 } ,
@@ -148,47 +161,44 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
148161 return null ;
149162 } ,
150163
151- updateHandMeshModel : function ( ) {
152- var frame = this . el . sceneEl . frame ;
153- var controller = this . el . components [ 'tracked-controls' ] && this . el . components [ 'tracked-controls' ] . controller ;
154- var referenceSpace = this . referenceSpace ;
155-
156- if ( ! controller || ! this . mesh || ! referenceSpace ) { return ; }
157- this . mesh . visible = false ;
158- for ( var inputjoint of controller . hand . values ( ) ) {
159- var bone ;
160- var jointPose ;
161- var jointTransform ;
162- jointPose = frame . getJointPose ( inputjoint , referenceSpace ) ;
163- bone = this . getBone ( inputjoint . jointName ) ;
164- if ( bone != null && jointPose ) {
165- jointTransform = jointPose . transform ;
166- this . mesh . visible = true ;
167- bone . position . copy ( jointTransform . position ) ;
168- bone . quaternion . copy ( jointTransform . orientation ) ;
164+ updateHandMeshModel : ( function ( ) {
165+ var jointPose = new THREE . Matrix4 ( ) ;
166+ return function ( ) {
167+ var jointPoses = this . jointPoses ;
168+ var controller = this . el . components [ 'tracked-controls' ] && this . el . components [ 'tracked-controls' ] . controller ;
169+ var i = 0 ;
170+
171+ if ( ! controller || ! this . mesh ) { return ; }
172+ this . mesh . visible = false ;
173+ if ( ! this . hasPoses ) { return ; }
174+ for ( var inputjoint of controller . hand . values ( ) ) {
175+ var bone = this . getBone ( inputjoint . jointName ) ;
176+ if ( bone != null ) {
177+ this . mesh . visible = true ;
178+ jointPose . fromArray ( jointPoses , i * 16 ) ;
179+ bone . position . setFromMatrixPosition ( jointPose ) ;
180+ bone . quaternion . setFromRotationMatrix ( jointPose ) ;
181+ }
182+ i ++ ;
169183 }
170- }
171- } ,
184+ } ;
185+ } ) ( ) ,
172186
173187 updateHandDotsModel : function ( ) {
174- var frame = this . el . sceneEl . frame ;
188+ var jointPoses = this . jointPoses ;
189+ var jointRadii = this . jointRadii ;
175190 var controller = this . el . components [ 'tracked-controls' ] && this . el . components [ 'tracked-controls' ] . controller ;
176- var trackedControlsWebXR = this . el . components [ 'tracked-controls-webxr' ] ;
177- var referenceSpace = trackedControlsWebXR . system . referenceSpace ;
178191 var jointEl ;
179192 var object3D ;
180- var jointPose ;
181- var i = 0 ;
182193
183- for ( var inputjoint of controller . hand . values ( ) ) {
184- jointEl = this . jointEls [ i ++ ] ;
194+ for ( var i = 0 ; i < controller . hand . size ; i ++ ) {
195+ jointEl = this . jointEls [ i ] ;
185196 object3D = jointEl . object3D ;
186- jointPose = frame . getJointPose ( inputjoint , referenceSpace ) ;
187- jointEl . object3D . visible = ! ! jointPose ;
188- if ( ! jointPose ) { continue ; }
189- object3D . matrix . elements = jointPose . transform . matrix ;
197+ jointEl . object3D . visible = this . hasPoses ;
198+ if ( ! this . hasPoses ) { continue ; }
199+ object3D . matrix . fromArray ( jointPoses , i * 16 ) ;
190200 object3D . matrix . decompose ( object3D . position , object3D . rotation , object3D . scale ) ;
191- jointEl . setAttribute ( 'scale' , { x : jointPose . radius , y : jointPose . radius , z : jointPose . radius } ) ;
201+ jointEl . setAttribute ( 'scale' , { x : jointRadii [ i ] , y : jointRadii [ i ] , z : jointRadii [ i ] } ) ;
192202 }
193203 } ,
194204
@@ -198,47 +208,32 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
198208
199209 detectPinch : ( function ( ) {
200210 var thumbTipPosition = new THREE . Vector3 ( ) ;
211+ var jointPose = new THREE . Matrix4 ( ) ;
201212 return function ( ) {
202- var frame = this . el . sceneEl . frame ;
203213 var indexTipPosition = this . indexTipPosition ;
204- var controller = this . el . components [ 'tracked-controls' ] && this . el . components [ 'tracked-controls' ] . controller ;
205- var trackedControlsWebXR = this . el . components [ 'tracked-controls-webxr' ] ;
206- var referenceSpace = this . referenceSpace || trackedControlsWebXR . system . referenceSpace ;
207- var indexTip = controller . hand . get ( 'index-finger-tip' ) ;
208- var thumbTip = controller . hand . get ( 'thumb-tip' ) ;
209- if ( ! indexTip ||
210- ! thumbTip ) { return ; }
211- var indexTipPose = frame . getJointPose ( indexTip , referenceSpace ) ;
212- var thumbTipPose = frame . getJointPose ( thumbTip , referenceSpace ) ;
214+ if ( ! this . hasPoses ) { return ; }
213215
214- if ( ! indexTipPose || ! thumbTipPose ) { return ; }
215-
216- thumbTipPosition . copy ( thumbTipPose . transform . position ) ;
217- indexTipPosition . copy ( indexTipPose . transform . position ) ;
216+ thumbTipPosition . setFromMatrixPosition ( jointPose . fromArray ( this . jointPoses , THUMB_TIP_INDEX * 16 ) ) ;
217+ indexTipPosition . setFromMatrixPosition ( jointPose . fromArray ( this . jointPoses , INDEX_TIP_INDEX * 16 ) ) ;
218218
219219 var distance = indexTipPosition . distanceTo ( thumbTipPosition ) ;
220220
221221 if ( distance < PINCH_START_DISTANCE && this . isPinched === false ) {
222222 this . isPinched = true ;
223223 this . pinchEventDetail . position . copy ( indexTipPosition ) . lerp ( thumbTipPosition , PINCH_POSITION_INTERPOLATION ) ;
224- this . pinchEventDetail . position . y += 1.5 ;
225224 this . el . emit ( 'pinchstarted' , this . pinchEventDetail ) ;
226225 }
227226
228227 if ( distance > PINCH_END_DISTANCE && this . isPinched === true ) {
229228 this . isPinched = false ;
230229 this . pinchEventDetail . position . copy ( indexTipPosition ) . lerp ( thumbTipPosition , PINCH_POSITION_INTERPOLATION ) ;
231- this . pinchEventDetail . position . y += 1.5 ;
232230 this . el . emit ( 'pinchended' , this . pinchEventDetail ) ;
233231 }
234232
235233 if ( this . isPinched ) {
236234 this . pinchEventDetail . position . copy ( indexTipPosition ) . lerp ( thumbTipPosition , PINCH_POSITION_INTERPOLATION ) ;
237- this . pinchEventDetail . position . y += 1.5 ;
238235 this . el . emit ( 'pinchmoved' , this . pinchEventDetail ) ;
239236 }
240-
241- indexTipPosition . y += 1.5 ;
242237 } ;
243238 } ) ( ) ,
244239
@@ -314,7 +309,7 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
314309 if ( ! this . skinnedMesh ) { return ; }
315310 this . bones = skinnedMesh . skeleton . bones ;
316311 this . el . removeObject3D ( 'mesh' ) ;
317- mesh . position . set ( 0 , 1.5 , 0 ) ;
312+ mesh . position . set ( 0 , 0 , 0 ) ;
318313 mesh . rotation . set ( 0 , 0 , 0 ) ;
319314 skinnedMesh . frustumCulled = false ;
320315 skinnedMesh . material = new THREE . MeshStandardMaterial ( { skinning : true , color : this . data . modelColor } ) ;
0 commit comments