-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
Copy pathhand-tracking-grab-controls.js
117 lines (96 loc) · 3.73 KB
/
hand-tracking-grab-controls.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import { registerComponent } from '../core/component.js';
import * as THREE from 'three';
registerComponent('hand-tracking-grab-controls', {
schema: {
hand: {default: 'right', oneOf: ['left', 'right']},
color: {type: 'color', default: 'white'},
hoverColor: {type: 'color', default: '#538df1'},
hoverEnabled: {default: false}
},
init: function () {
var el = this.el;
var data = this.data;
var trackedObject3DVariable;
if (data.hand === 'right') {
trackedObject3DVariable = 'components.hand-tracking-controls.bones.3';
} else {
trackedObject3DVariable = 'components.hand-tracking-controls.bones.21';
}
el.setAttribute('hand-tracking-controls', {hand: data.hand});
el.setAttribute('obb-collider', {trackedObject3D: trackedObject3DVariable, size: 0.04});
this.auxMatrix = new THREE.Matrix4();
this.onCollisionStarted = this.onCollisionStarted.bind(this);
this.el.addEventListener('obbcollisionstarted', this.onCollisionStarted);
this.onCollisionEnded = this.onCollisionEnded.bind(this);
this.el.addEventListener('obbcollisionended', this.onCollisionEnded);
this.onPinchStarted = this.onPinchStarted.bind(this);
this.el.addEventListener('pinchstarted', this.onPinchStarted);
this.onPinchEnded = this.onPinchEnded.bind(this);
this.el.addEventListener('pinchended', this.onPinchEnded);
},
transferEntityOwnership: function () {
var grabbingElComponent;
var grabbingEls = this.el.sceneEl.querySelectorAll('[hand-tracking-grab-controls]');
for (var i = 0; i < grabbingEls.length; ++i) {
grabbingElComponent = grabbingEls[i].components['hand-tracking-grab-controls'];
if (grabbingElComponent === this) { continue; }
if (this.grabbedEl && this.grabbedEl === grabbingElComponent.grabbedEl) {
grabbingElComponent.releaseGrabbedEntity();
}
}
return false;
},
onCollisionStarted: function (evt) {
var withEl = evt.detail.withEl;
if (this.collidedEl) { return; }
if (!withEl.getAttribute('grabbable')) { return; }
this.collidedEl = withEl;
this.grabbingObject3D = evt.detail.trackedObject3D;
if (this.data.hoverEnabled) {
this.el.setAttribute('hand-tracking-controls', 'modelColor', this.data.hoverColor);
}
},
onCollisionEnded: function () {
this.collidedEl = undefined;
if (this.grabbedEl) { return; }
this.grabbingObject3D = undefined;
if (this.data.hoverEnabled) {
this.el.setAttribute('hand-tracking-controls', 'modelColor', this.data.color);
}
},
onPinchStarted: function (evt) {
if (!this.collidedEl) { return; }
this.grabbedEl = this.collidedEl;
this.transferEntityOwnership();
this.grab();
},
onPinchEnded: function () {
this.releaseGrabbedEntity();
},
releaseGrabbedEntity: function () {
var grabbedEl = this.grabbedEl;
if (!grabbedEl) { return; }
var child = grabbedEl.object3D;
var parent = child.parent;
var newParent = this.originalParent;
child.applyMatrix4(parent.matrixWorld);
child.applyMatrix4(this.auxMatrix.copy(newParent.matrixWorld).invert());
parent.remove(child);
newParent.add(child);
this.el.emit('grabended', {grabbedEl: grabbedEl});
this.grabbedEl = undefined;
this.originalParent = undefined;
},
grab: function () {
var grabbedEl = this.grabbedEl;
var child = grabbedEl.object3D;
var parent = child.parent;
this.originalParent = parent;
var newParent = this.el.components['hand-tracking-controls'].wristObject3D;
child.applyMatrix4(parent.matrixWorld);
child.applyMatrix4(this.auxMatrix.copy(newParent.matrixWorld).invert());
parent.remove(child);
newParent.add(child);
this.el.emit('grabstarted', {grabbedEl: grabbedEl});
}
});