Skip to content

Commit 97be815

Browse files
committed
Fix hand tracking controls to account for latest changes in standard spec
1 parent 6d6490a commit 97be815

File tree

1 file changed

+88
-59
lines changed

1 file changed

+88
-59
lines changed

src/components/hand-tracking-controls.js

Lines changed: 88 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
/* global THREE, XRRigidTransform, XRHand */
1+
/* global THREE, XRRigidTransform */
22
var registerComponent = require('../core/component').registerComponent;
33
var bind = require('../utils/bind');
44

55
var trackedControlsUtils = require('../utils/tracked-controls');
66
var checkControllerPresentAndSetup = trackedControlsUtils.checkControllerPresentAndSetup;
77

8-
var JOINTS_NUMBER = 25;
9-
108
var LEFT_HAND_MODEL_URL = 'https://cdn.aframe.io/controllers/oculus-hands/unity/left.glb';
119
var RIGHT_HAND_MODEL_URL = 'https://cdn.aframe.io/controllers/oculus-hands/unity/right.glb';
1210

@@ -15,34 +13,59 @@ var BONE_PREFIX = {
1513
right: 'b_r_'
1614
};
1715

18-
var BONE_MAPPING = [
16+
var JOINTS = [
1917
'wrist',
20-
'thumb1',
21-
'thumb2',
22-
'thumb3',
23-
'thumb_null',
24-
null,
25-
'index1',
26-
'index2',
27-
'index3',
28-
'index_null',
29-
null,
30-
'middle1',
31-
'middle2',
32-
'middle3',
33-
'middle_null',
34-
null,
35-
'ring1',
36-
'ring2',
37-
'ring3',
38-
'ring_null',
39-
'pinky0',
40-
'pinky1',
41-
'pinky2',
42-
'pinky3',
43-
'pinky_null'
18+
'thumb-metacarpal',
19+
'thumb-phalanx-proximal',
20+
'thumb-phalanx-distal',
21+
'thumb-tip',
22+
'index-finger-metacarpal',
23+
'index-finger-phalanx-proximal',
24+
'index-finger-phalanx-intermediate',
25+
'index-finger-phalanx-distal',
26+
'index-finger-tip',
27+
'middle-finger-metacarpal',
28+
'middle-finger-phalanx-proximal',
29+
'middle-finger-phalanx-intermediate',
30+
'middle-finger-phalanx-distal',
31+
'middle-finger-tip',
32+
'ring-finger-metacarpal',
33+
'ring-finger-phalanx-proximal',
34+
'ring-finger-phalanx-intermediate',
35+
'ring-finger-phalanx-distal',
36+
'ring-finger-tip',
37+
'pinky-finger-metacarpal',
38+
'pinky-finger-phalanx-proximal',
39+
'pinky-finger-phalanx-intermediate',
40+
'pinky-finger-phalanx-distal',
41+
'pinky-finger-tip'
4442
];
4543

44+
var BONE_MAPPING = {
45+
'wrist': 'wrist',
46+
'thumb-metacarpal': 'thumb1',
47+
'thumb-phalanx-proximal': 'thumb2',
48+
'thumb-phalanx-distal': 'thumb3',
49+
'thumb-tip': 'thumb_null',
50+
'index-finger-phalanx-proximal': 'index1',
51+
'index-finger-phalanx-intermediate': 'index2',
52+
'index-finger-phalanx-distal': 'index3',
53+
'index-finger-tip': 'index_null',
54+
'middle-finger-phalanx-proximal': 'middle1',
55+
'middle-finger-phalanx-intermediate': 'middle2',
56+
'middle-finger-phalanx-distal': 'middle3',
57+
'middle-finger-tip': 'middle_null',
58+
'ring-finger-phalanx-proximal': 'ring1',
59+
'ring-finger-phalanx-intermediate': 'ring2',
60+
'ring-finger-phalanx-distal': 'ring3',
61+
'ring-finger-tip': 'ring_null',
62+
'pinky-finger-metacarpal': 'pinky0',
63+
'pinky-finger-phalanx-proximal': 'pinky1',
64+
'pinky-finger-phalanx-intermediate': 'pinky2',
65+
'pinky-finger-phalanx-distal': 'pinky3',
66+
'pinky-finger-tip': 'pinky_null'
67+
};
68+
4669
var PINCH_START_DISTANCE = 0.015;
4770
var PINCH_END_DISTANCE = 0.03;
4871
var PINCH_POSITION_INTERPOLATION = 0.5;
@@ -147,19 +170,28 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
147170
}
148171
},
149172

173+
getBone: function (name) {
174+
var bones = this.bones;
175+
for (var i = 0; i < bones.length; i++) {
176+
if (bones[i].name === name) { return bones[i]; }
177+
}
178+
return null;
179+
},
180+
150181
updateHandMeshModel: function () {
182+
var frame = this.el.sceneEl.frame;
151183
var controller = this.el.components['tracked-controls'] && this.el.components['tracked-controls'].controller;
152184
var referenceSpace = this.referenceSpace;
185+
153186
if (!controller || !this.mesh || !referenceSpace) { return; }
154187
this.mesh.visible = false;
155-
for (var i = 0; i < controller.hand.length; i++) {
188+
for (var inputjoint of controller.hand.values()) {
156189
var bone;
157190
var jointPose;
158191
var jointTransform;
159-
if (!controller.hand[i]) { continue; }
160-
jointPose = this.el.sceneEl.frame.getJointPose(controller.hand[i], referenceSpace);
161-
if (BONE_MAPPING[i] == null) { continue; }
162-
bone = this.getBone(BONE_PREFIX[this.data.hand] + BONE_MAPPING[i]);
192+
jointPose = frame.getJointPose(inputjoint, referenceSpace);
193+
if (!BONE_MAPPING[inputjoint.jointName]) { continue; }
194+
bone = this.getBone(BONE_PREFIX[this.data.hand] + BONE_MAPPING[inputjoint.jointName]);
163195
if (bone != null && jointPose) {
164196
jointTransform = jointPose.transform;
165197
this.mesh.visible = true;
@@ -169,31 +201,25 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
169201
}
170202
},
171203

172-
getBone: function (name) {
173-
var bones = this.bones;
174-
for (var i = 0; i < bones.length; i++) {
175-
if (bones[i].name === name) { return bones[i]; }
176-
}
177-
return null;
178-
},
179-
180204
updateHandDotsModel: function () {
181205
var frame = this.el.sceneEl.frame;
182206
var controller = this.el.components['tracked-controls'] && this.el.components['tracked-controls'].controller;
183207
var trackedControlsWebXR = this.el.components['tracked-controls-webxr'];
184208
var referenceSpace = trackedControlsWebXR.system.referenceSpace;
185-
for (var i = 0; i < this.jointEls.length; ++i) {
186-
var jointEl = this.jointEls[i];
187-
jointEl.object3D.visible = !!controller.hand[i];
188-
if (controller.hand[i]) {
189-
var object3D = jointEl.object3D;
190-
var pose = frame.getJointPose(controller.hand[i], referenceSpace);
191-
jointEl.object3D.visible = !!pose;
192-
if (!pose) { continue; }
193-
object3D.matrix.elements = pose.transform.matrix;
194-
object3D.matrix.decompose(object3D.position, object3D.rotation, object3D.scale);
195-
jointEl.setAttribute('scale', {x: pose.radius, y: pose.radius, z: pose.radius});
196-
}
209+
var jointEl;
210+
var object3D;
211+
var jointPose;
212+
var i = 0;
213+
214+
for (var inputjoint of controller.hand.values()) {
215+
jointEl = this.jointEls[i++];
216+
object3D = jointEl.object3D;
217+
jointPose = frame.getJointPose(inputjoint, referenceSpace);
218+
jointEl.object3D.visible = !!jointPose;
219+
if (!jointPose) { continue; }
220+
object3D.matrix.elements = jointPose.transform.matrix;
221+
object3D.matrix.decompose(object3D.position, object3D.rotation, object3D.scale);
222+
jointEl.setAttribute('scale', {x: jointPose.radius, y: jointPose.radius, z: jointPose.radius});
197223
}
198224
},
199225

@@ -209,10 +235,12 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
209235
var controller = this.el.components['tracked-controls'] && this.el.components['tracked-controls'].controller;
210236
var trackedControlsWebXR = this.el.components['tracked-controls-webxr'];
211237
var referenceSpace = this.referenceSpace || trackedControlsWebXR.system.referenceSpace;
212-
if (!controller.hand[XRHand.INDEX_PHALANX_TIP] ||
213-
!controller.hand[XRHand.THUMB_PHALANX_TIP]) { return; }
214-
var indexTipPose = frame.getJointPose(controller.hand[XRHand.INDEX_PHALANX_TIP], referenceSpace);
215-
var thumbTipPose = frame.getJointPose(controller.hand[XRHand.THUMB_PHALANX_TIP], referenceSpace);
238+
var indexTip = controller.hand.get('index-finger-tip');
239+
var thumbTip = controller.hand.get('thumb-tip');
240+
if (!indexTip ||
241+
!thumbTip) { return; }
242+
var indexTipPose = frame.getJointPose(indexTip, referenceSpace);
243+
var thumbTipPose = frame.getJointPose(thumbTip, referenceSpace);
216244

217245
if (!indexTipPose || !thumbTipPose) { return; }
218246

@@ -275,11 +303,12 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
275303
controller = this.el.components['tracked-controls'] && this.el.components['tracked-controls'].controller;
276304
if (!this.el.getObject3D('mesh')) { return; }
277305
if (!controller || !controller.hand || !controller.hand[0]) {
278-
this.el.removeObject3D('mesh');
306+
this.el.getObject3D('mesh').visible = false;
279307
}
280308
},
281309

282310
initDefaultModel: function () {
311+
if (this.el.getObject3D('mesh')) { return; }
283312
if (this.data.modelStyle === 'dots') {
284313
this.initDotsModel();
285314
}
@@ -292,7 +321,7 @@ module.exports.Component = registerComponent('hand-tracking-controls', {
292321
initDotsModel: function () {
293322
// Add models just once.
294323
if (this.jointEls.length !== 0) { return; }
295-
for (var i = 0; i < JOINTS_NUMBER; ++i) {
324+
for (var i = 0; i < JOINTS.length; ++i) {
296325
var jointEl = this.jointEl = document.createElement('a-entity');
297326
jointEl.setAttribute('geometry', {
298327
primitive: 'sphere',

0 commit comments

Comments
 (0)