urdf-loader 0.10.4 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +578 -579
- package/package.json +2 -2
- package/src/URDFClasses.d.ts +66 -66
- package/src/URDFClasses.js +395 -402
- package/src/URDFDragControls.js +329 -329
- package/src/URDFLoader.d.ts +36 -36
- package/src/URDFLoader.js +664 -664
- package/src/urdf-manipulator-element.js +155 -150
- package/src/urdf-viewer-element.js +616 -551
- package/umd/URDFLoader.js +1047 -1054
- package/umd/URDFLoader.js.map +1 -1
- package/umd/urdf-manipulator-element.js +475 -470
- package/umd/urdf-manipulator-element.js.map +1 -1
- package/umd/urdf-viewer-element.js +609 -545
- package/umd/urdf-viewer-element.js.map +1 -1
package/src/URDFDragControls.js
CHANGED
|
@@ -1,329 +1,329 @@
|
|
|
1
|
-
import { Raycaster, Vector3, Plane, Vector2 } from 'three';
|
|
2
|
-
|
|
3
|
-
// Find the nearest parent that is a joint
|
|
4
|
-
function isJoint(j) {
|
|
5
|
-
|
|
6
|
-
return j.isURDFJoint && j.jointType !== 'fixed';
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
function findNearestJoint(child) {
|
|
11
|
-
|
|
12
|
-
let curr = child;
|
|
13
|
-
while (curr) {
|
|
14
|
-
|
|
15
|
-
if (isJoint(curr)) {
|
|
16
|
-
|
|
17
|
-
return curr;
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
curr = curr.parent;
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return curr;
|
|
26
|
-
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const prevHitPoint = new Vector3();
|
|
30
|
-
const newHitPoint = new Vector3();
|
|
31
|
-
const pivotPoint = new Vector3();
|
|
32
|
-
const tempVector = new Vector3();
|
|
33
|
-
const tempVector2 = new Vector3();
|
|
34
|
-
const projectedStartPoint = new Vector3();
|
|
35
|
-
const projectedEndPoint = new Vector3();
|
|
36
|
-
const plane = new Plane();
|
|
37
|
-
export class URDFDragControls {
|
|
38
|
-
|
|
39
|
-
constructor(scene) {
|
|
40
|
-
|
|
41
|
-
this.enabled = true;
|
|
42
|
-
this.scene = scene;
|
|
43
|
-
this.raycaster = new Raycaster();
|
|
44
|
-
this.initialGrabPoint = new Vector3();
|
|
45
|
-
|
|
46
|
-
this.hitDistance = -1;
|
|
47
|
-
this.hovered = null;
|
|
48
|
-
this.manipulating = null;
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
update() {
|
|
53
|
-
|
|
54
|
-
const {
|
|
55
|
-
raycaster,
|
|
56
|
-
hovered,
|
|
57
|
-
manipulating,
|
|
58
|
-
scene,
|
|
59
|
-
} = this;
|
|
60
|
-
|
|
61
|
-
if (manipulating) {
|
|
62
|
-
|
|
63
|
-
return;
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let hoveredJoint = null;
|
|
68
|
-
const intersections = raycaster.intersectObject(scene, true);
|
|
69
|
-
if (intersections.length !== 0) {
|
|
70
|
-
|
|
71
|
-
const hit = intersections[0];
|
|
72
|
-
this.hitDistance = hit.distance;
|
|
73
|
-
hoveredJoint = findNearestJoint(hit.object);
|
|
74
|
-
this.initialGrabPoint.copy(hit.point);
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (hoveredJoint !== hovered) {
|
|
79
|
-
|
|
80
|
-
if (hovered) {
|
|
81
|
-
|
|
82
|
-
this.onUnhover(hovered);
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
this.hovered = hoveredJoint;
|
|
87
|
-
|
|
88
|
-
if (hoveredJoint) {
|
|
89
|
-
|
|
90
|
-
this.onHover(hoveredJoint);
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
updateJoint(joint, angle) {
|
|
99
|
-
|
|
100
|
-
joint.setJointValue(angle);
|
|
101
|
-
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
onDragStart(joint) {
|
|
105
|
-
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
onDragEnd(joint) {
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
onHover(joint) {
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
onUnhover(joint) {
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
121
|
-
|
|
122
|
-
// set up the plane
|
|
123
|
-
tempVector
|
|
124
|
-
.copy(joint.axis)
|
|
125
|
-
.transformDirection(joint.matrixWorld)
|
|
126
|
-
.normalize();
|
|
127
|
-
pivotPoint
|
|
128
|
-
.set(0, 0, 0)
|
|
129
|
-
.applyMatrix4(joint.matrixWorld);
|
|
130
|
-
plane
|
|
131
|
-
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
132
|
-
|
|
133
|
-
// project the drag points onto the plane
|
|
134
|
-
plane.projectPoint(startPoint, projectedStartPoint);
|
|
135
|
-
plane.projectPoint(endPoint, projectedEndPoint);
|
|
136
|
-
|
|
137
|
-
// get the directions relative to the pivot
|
|
138
|
-
projectedStartPoint.sub(pivotPoint);
|
|
139
|
-
projectedEndPoint.sub(pivotPoint);
|
|
140
|
-
|
|
141
|
-
tempVector.crossVectors(projectedStartPoint, projectedEndPoint);
|
|
142
|
-
|
|
143
|
-
const direction = Math.sign(tempVector.dot(plane.normal));
|
|
144
|
-
return direction * projectedEndPoint.angleTo(projectedStartPoint);
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
getPrismaticDelta(joint, startPoint, endPoint) {
|
|
149
|
-
|
|
150
|
-
tempVector.subVectors(endPoint, startPoint);
|
|
151
|
-
plane
|
|
152
|
-
.normal
|
|
153
|
-
.copy(joint.axis)
|
|
154
|
-
.transformDirection(joint.parent.matrixWorld)
|
|
155
|
-
.normalize();
|
|
156
|
-
|
|
157
|
-
return tempVector.dot(plane.normal);
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
moveRay(toRay) {
|
|
162
|
-
|
|
163
|
-
const { raycaster, hitDistance, manipulating } = this;
|
|
164
|
-
const { ray } = raycaster;
|
|
165
|
-
|
|
166
|
-
if (manipulating) {
|
|
167
|
-
|
|
168
|
-
ray.at(hitDistance, prevHitPoint);
|
|
169
|
-
toRay.at(hitDistance, newHitPoint);
|
|
170
|
-
|
|
171
|
-
let delta = 0;
|
|
172
|
-
if (manipulating.jointType === 'revolute' || manipulating.jointType === 'continuous') {
|
|
173
|
-
|
|
174
|
-
delta = this.getRevoluteDelta(manipulating, prevHitPoint, newHitPoint);
|
|
175
|
-
|
|
176
|
-
} else if (manipulating.jointType === 'prismatic') {
|
|
177
|
-
|
|
178
|
-
delta = this.getPrismaticDelta(manipulating, prevHitPoint, newHitPoint);
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (delta) {
|
|
183
|
-
|
|
184
|
-
this.updateJoint(manipulating, manipulating.angle + delta);
|
|
185
|
-
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
this.raycaster.ray.copy(toRay);
|
|
191
|
-
this.update();
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
setGrabbed(grabbed) {
|
|
196
|
-
|
|
197
|
-
const { hovered, manipulating } = this;
|
|
198
|
-
|
|
199
|
-
if (grabbed) {
|
|
200
|
-
|
|
201
|
-
if (manipulating !== null || hovered === null) {
|
|
202
|
-
|
|
203
|
-
return;
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
this.manipulating = hovered;
|
|
208
|
-
this.onDragStart(hovered);
|
|
209
|
-
|
|
210
|
-
} else {
|
|
211
|
-
|
|
212
|
-
if (this.manipulating === null) {
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
this.onDragEnd(this.manipulating);
|
|
217
|
-
this.manipulating = null;
|
|
218
|
-
this.update();
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
export class PointerURDFDragControls extends URDFDragControls {
|
|
227
|
-
|
|
228
|
-
constructor(scene, camera, domElement) {
|
|
229
|
-
|
|
230
|
-
super(scene);
|
|
231
|
-
this.camera = camera;
|
|
232
|
-
this.domElement = domElement;
|
|
233
|
-
|
|
234
|
-
const raycaster = new Raycaster();
|
|
235
|
-
const mouse = new Vector2();
|
|
236
|
-
|
|
237
|
-
function updateMouse(e) {
|
|
238
|
-
|
|
239
|
-
mouse.x = ((e.pageX - domElement.offsetLeft) / domElement.offsetWidth) * 2 - 1;
|
|
240
|
-
mouse.y = -((e.pageY - domElement.offsetTop) / domElement.offsetHeight) * 2 + 1;
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
this._mouseDown = e => {
|
|
245
|
-
|
|
246
|
-
updateMouse(e);
|
|
247
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
248
|
-
this.moveRay(raycaster.ray);
|
|
249
|
-
this.setGrabbed(true);
|
|
250
|
-
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
this._mouseMove = e => {
|
|
254
|
-
|
|
255
|
-
updateMouse(e);
|
|
256
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
257
|
-
this.moveRay(raycaster.ray);
|
|
258
|
-
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
this._mouseUp = e => {
|
|
262
|
-
|
|
263
|
-
updateMouse(e);
|
|
264
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
265
|
-
this.moveRay(raycaster.ray);
|
|
266
|
-
this.setGrabbed(false);
|
|
267
|
-
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
domElement.addEventListener('mousedown', this._mouseDown);
|
|
271
|
-
domElement.addEventListener('mousemove', this._mouseMove);
|
|
272
|
-
domElement.addEventListener('mouseup', this._mouseUp);
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
277
|
-
|
|
278
|
-
const { camera, initialGrabPoint } = this;
|
|
279
|
-
|
|
280
|
-
// set up the plane
|
|
281
|
-
tempVector
|
|
282
|
-
.copy(joint.axis)
|
|
283
|
-
.transformDirection(joint.matrixWorld)
|
|
284
|
-
.normalize();
|
|
285
|
-
pivotPoint
|
|
286
|
-
.set(0, 0, 0)
|
|
287
|
-
.applyMatrix4(joint.matrixWorld);
|
|
288
|
-
plane
|
|
289
|
-
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
290
|
-
|
|
291
|
-
tempVector
|
|
292
|
-
.copy(camera.position)
|
|
293
|
-
.sub(initialGrabPoint)
|
|
294
|
-
.normalize();
|
|
295
|
-
|
|
296
|
-
// if looking into the plane of rotation
|
|
297
|
-
if (Math.abs(tempVector.dot(plane.normal)) > 0.3) {
|
|
298
|
-
|
|
299
|
-
return super.getRevoluteDelta(joint, startPoint, endPoint);
|
|
300
|
-
|
|
301
|
-
} else {
|
|
302
|
-
|
|
303
|
-
// get the up direction
|
|
304
|
-
tempVector.set(0, 1, 0).transformDirection(camera.matrixWorld);
|
|
305
|
-
|
|
306
|
-
// get points projected onto the plane of rotation
|
|
307
|
-
plane.projectPoint(startPoint, projectedStartPoint);
|
|
308
|
-
plane.projectPoint(endPoint, projectedEndPoint);
|
|
309
|
-
|
|
310
|
-
tempVector.set(0, 0, -1).transformDirection(camera.matrixWorld);
|
|
311
|
-
tempVector.cross(plane.normal);
|
|
312
|
-
tempVector2.subVectors(endPoint, startPoint);
|
|
313
|
-
|
|
314
|
-
return tempVector.dot(tempVector2);
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
dispose() {
|
|
321
|
-
|
|
322
|
-
const { domElement } = this;
|
|
323
|
-
domElement.removeEventListener('mousedown', this._mouseDown);
|
|
324
|
-
domElement.removeEventListener('mousemove', this._mouseMove);
|
|
325
|
-
domElement.removeEventListener('mouseup', this._mouseUp);
|
|
326
|
-
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
}
|
|
1
|
+
import { Raycaster, Vector3, Plane, Vector2 } from 'three';
|
|
2
|
+
|
|
3
|
+
// Find the nearest parent that is a joint
|
|
4
|
+
function isJoint(j) {
|
|
5
|
+
|
|
6
|
+
return j.isURDFJoint && j.jointType !== 'fixed';
|
|
7
|
+
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
function findNearestJoint(child) {
|
|
11
|
+
|
|
12
|
+
let curr = child;
|
|
13
|
+
while (curr) {
|
|
14
|
+
|
|
15
|
+
if (isJoint(curr)) {
|
|
16
|
+
|
|
17
|
+
return curr;
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
curr = curr.parent;
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return curr;
|
|
26
|
+
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const prevHitPoint = new Vector3();
|
|
30
|
+
const newHitPoint = new Vector3();
|
|
31
|
+
const pivotPoint = new Vector3();
|
|
32
|
+
const tempVector = new Vector3();
|
|
33
|
+
const tempVector2 = new Vector3();
|
|
34
|
+
const projectedStartPoint = new Vector3();
|
|
35
|
+
const projectedEndPoint = new Vector3();
|
|
36
|
+
const plane = new Plane();
|
|
37
|
+
export class URDFDragControls {
|
|
38
|
+
|
|
39
|
+
constructor(scene) {
|
|
40
|
+
|
|
41
|
+
this.enabled = true;
|
|
42
|
+
this.scene = scene;
|
|
43
|
+
this.raycaster = new Raycaster();
|
|
44
|
+
this.initialGrabPoint = new Vector3();
|
|
45
|
+
|
|
46
|
+
this.hitDistance = -1;
|
|
47
|
+
this.hovered = null;
|
|
48
|
+
this.manipulating = null;
|
|
49
|
+
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
update() {
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
raycaster,
|
|
56
|
+
hovered,
|
|
57
|
+
manipulating,
|
|
58
|
+
scene,
|
|
59
|
+
} = this;
|
|
60
|
+
|
|
61
|
+
if (manipulating) {
|
|
62
|
+
|
|
63
|
+
return;
|
|
64
|
+
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
let hoveredJoint = null;
|
|
68
|
+
const intersections = raycaster.intersectObject(scene, true);
|
|
69
|
+
if (intersections.length !== 0) {
|
|
70
|
+
|
|
71
|
+
const hit = intersections[0];
|
|
72
|
+
this.hitDistance = hit.distance;
|
|
73
|
+
hoveredJoint = findNearestJoint(hit.object);
|
|
74
|
+
this.initialGrabPoint.copy(hit.point);
|
|
75
|
+
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (hoveredJoint !== hovered) {
|
|
79
|
+
|
|
80
|
+
if (hovered) {
|
|
81
|
+
|
|
82
|
+
this.onUnhover(hovered);
|
|
83
|
+
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
this.hovered = hoveredJoint;
|
|
87
|
+
|
|
88
|
+
if (hoveredJoint) {
|
|
89
|
+
|
|
90
|
+
this.onHover(hoveredJoint);
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
updateJoint(joint, angle) {
|
|
99
|
+
|
|
100
|
+
joint.setJointValue(angle);
|
|
101
|
+
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
onDragStart(joint) {
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
onDragEnd(joint) {
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
onHover(joint) {
|
|
113
|
+
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
onUnhover(joint) {
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
121
|
+
|
|
122
|
+
// set up the plane
|
|
123
|
+
tempVector
|
|
124
|
+
.copy(joint.axis)
|
|
125
|
+
.transformDirection(joint.matrixWorld)
|
|
126
|
+
.normalize();
|
|
127
|
+
pivotPoint
|
|
128
|
+
.set(0, 0, 0)
|
|
129
|
+
.applyMatrix4(joint.matrixWorld);
|
|
130
|
+
plane
|
|
131
|
+
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
132
|
+
|
|
133
|
+
// project the drag points onto the plane
|
|
134
|
+
plane.projectPoint(startPoint, projectedStartPoint);
|
|
135
|
+
plane.projectPoint(endPoint, projectedEndPoint);
|
|
136
|
+
|
|
137
|
+
// get the directions relative to the pivot
|
|
138
|
+
projectedStartPoint.sub(pivotPoint);
|
|
139
|
+
projectedEndPoint.sub(pivotPoint);
|
|
140
|
+
|
|
141
|
+
tempVector.crossVectors(projectedStartPoint, projectedEndPoint);
|
|
142
|
+
|
|
143
|
+
const direction = Math.sign(tempVector.dot(plane.normal));
|
|
144
|
+
return direction * projectedEndPoint.angleTo(projectedStartPoint);
|
|
145
|
+
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
getPrismaticDelta(joint, startPoint, endPoint) {
|
|
149
|
+
|
|
150
|
+
tempVector.subVectors(endPoint, startPoint);
|
|
151
|
+
plane
|
|
152
|
+
.normal
|
|
153
|
+
.copy(joint.axis)
|
|
154
|
+
.transformDirection(joint.parent.matrixWorld)
|
|
155
|
+
.normalize();
|
|
156
|
+
|
|
157
|
+
return tempVector.dot(plane.normal);
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
moveRay(toRay) {
|
|
162
|
+
|
|
163
|
+
const { raycaster, hitDistance, manipulating } = this;
|
|
164
|
+
const { ray } = raycaster;
|
|
165
|
+
|
|
166
|
+
if (manipulating) {
|
|
167
|
+
|
|
168
|
+
ray.at(hitDistance, prevHitPoint);
|
|
169
|
+
toRay.at(hitDistance, newHitPoint);
|
|
170
|
+
|
|
171
|
+
let delta = 0;
|
|
172
|
+
if (manipulating.jointType === 'revolute' || manipulating.jointType === 'continuous') {
|
|
173
|
+
|
|
174
|
+
delta = this.getRevoluteDelta(manipulating, prevHitPoint, newHitPoint);
|
|
175
|
+
|
|
176
|
+
} else if (manipulating.jointType === 'prismatic') {
|
|
177
|
+
|
|
178
|
+
delta = this.getPrismaticDelta(manipulating, prevHitPoint, newHitPoint);
|
|
179
|
+
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (delta) {
|
|
183
|
+
|
|
184
|
+
this.updateJoint(manipulating, manipulating.angle + delta);
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
this.raycaster.ray.copy(toRay);
|
|
191
|
+
this.update();
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
setGrabbed(grabbed) {
|
|
196
|
+
|
|
197
|
+
const { hovered, manipulating } = this;
|
|
198
|
+
|
|
199
|
+
if (grabbed) {
|
|
200
|
+
|
|
201
|
+
if (manipulating !== null || hovered === null) {
|
|
202
|
+
|
|
203
|
+
return;
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
this.manipulating = hovered;
|
|
208
|
+
this.onDragStart(hovered);
|
|
209
|
+
|
|
210
|
+
} else {
|
|
211
|
+
|
|
212
|
+
if (this.manipulating === null) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this.onDragEnd(this.manipulating);
|
|
217
|
+
this.manipulating = null;
|
|
218
|
+
this.update();
|
|
219
|
+
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export class PointerURDFDragControls extends URDFDragControls {
|
|
227
|
+
|
|
228
|
+
constructor(scene, camera, domElement) {
|
|
229
|
+
|
|
230
|
+
super(scene);
|
|
231
|
+
this.camera = camera;
|
|
232
|
+
this.domElement = domElement;
|
|
233
|
+
|
|
234
|
+
const raycaster = new Raycaster();
|
|
235
|
+
const mouse = new Vector2();
|
|
236
|
+
|
|
237
|
+
function updateMouse(e) {
|
|
238
|
+
|
|
239
|
+
mouse.x = ((e.pageX - domElement.offsetLeft) / domElement.offsetWidth) * 2 - 1;
|
|
240
|
+
mouse.y = -((e.pageY - domElement.offsetTop) / domElement.offsetHeight) * 2 + 1;
|
|
241
|
+
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
this._mouseDown = e => {
|
|
245
|
+
|
|
246
|
+
updateMouse(e);
|
|
247
|
+
raycaster.setFromCamera(mouse, this.camera);
|
|
248
|
+
this.moveRay(raycaster.ray);
|
|
249
|
+
this.setGrabbed(true);
|
|
250
|
+
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
this._mouseMove = e => {
|
|
254
|
+
|
|
255
|
+
updateMouse(e);
|
|
256
|
+
raycaster.setFromCamera(mouse, this.camera);
|
|
257
|
+
this.moveRay(raycaster.ray);
|
|
258
|
+
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
this._mouseUp = e => {
|
|
262
|
+
|
|
263
|
+
updateMouse(e);
|
|
264
|
+
raycaster.setFromCamera(mouse, this.camera);
|
|
265
|
+
this.moveRay(raycaster.ray);
|
|
266
|
+
this.setGrabbed(false);
|
|
267
|
+
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
domElement.addEventListener('mousedown', this._mouseDown);
|
|
271
|
+
domElement.addEventListener('mousemove', this._mouseMove);
|
|
272
|
+
domElement.addEventListener('mouseup', this._mouseUp);
|
|
273
|
+
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
277
|
+
|
|
278
|
+
const { camera, initialGrabPoint } = this;
|
|
279
|
+
|
|
280
|
+
// set up the plane
|
|
281
|
+
tempVector
|
|
282
|
+
.copy(joint.axis)
|
|
283
|
+
.transformDirection(joint.matrixWorld)
|
|
284
|
+
.normalize();
|
|
285
|
+
pivotPoint
|
|
286
|
+
.set(0, 0, 0)
|
|
287
|
+
.applyMatrix4(joint.matrixWorld);
|
|
288
|
+
plane
|
|
289
|
+
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
290
|
+
|
|
291
|
+
tempVector
|
|
292
|
+
.copy(camera.position)
|
|
293
|
+
.sub(initialGrabPoint)
|
|
294
|
+
.normalize();
|
|
295
|
+
|
|
296
|
+
// if looking into the plane of rotation
|
|
297
|
+
if (Math.abs(tempVector.dot(plane.normal)) > 0.3) {
|
|
298
|
+
|
|
299
|
+
return super.getRevoluteDelta(joint, startPoint, endPoint);
|
|
300
|
+
|
|
301
|
+
} else {
|
|
302
|
+
|
|
303
|
+
// get the up direction
|
|
304
|
+
tempVector.set(0, 1, 0).transformDirection(camera.matrixWorld);
|
|
305
|
+
|
|
306
|
+
// get points projected onto the plane of rotation
|
|
307
|
+
plane.projectPoint(startPoint, projectedStartPoint);
|
|
308
|
+
plane.projectPoint(endPoint, projectedEndPoint);
|
|
309
|
+
|
|
310
|
+
tempVector.set(0, 0, -1).transformDirection(camera.matrixWorld);
|
|
311
|
+
tempVector.cross(plane.normal);
|
|
312
|
+
tempVector2.subVectors(endPoint, startPoint);
|
|
313
|
+
|
|
314
|
+
return tempVector.dot(tempVector2);
|
|
315
|
+
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
dispose() {
|
|
321
|
+
|
|
322
|
+
const { domElement } = this;
|
|
323
|
+
domElement.removeEventListener('mousedown', this._mouseDown);
|
|
324
|
+
domElement.removeEventListener('mousemove', this._mouseMove);
|
|
325
|
+
domElement.removeEventListener('mouseup', this._mouseUp);
|
|
326
|
+
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
}
|