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
|
@@ -29,478 +29,483 @@
|
|
|
29
29
|
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
30
30
|
var URDFViewer__default = /*#__PURE__*/_interopDefaultLegacy(URDFViewer);
|
|
31
31
|
|
|
32
|
-
// Find the nearest parent that is a joint
|
|
33
|
-
function isJoint(j) {
|
|
34
|
-
|
|
35
|
-
return j.isURDFJoint && j.jointType !== 'fixed';
|
|
36
|
-
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
function findNearestJoint(child) {
|
|
40
|
-
|
|
41
|
-
let curr = child;
|
|
42
|
-
while (curr) {
|
|
43
|
-
|
|
44
|
-
if (isJoint(curr)) {
|
|
45
|
-
|
|
46
|
-
return curr;
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
curr = curr.parent;
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return curr;
|
|
55
|
-
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const prevHitPoint = new THREE.Vector3();
|
|
59
|
-
const newHitPoint = new THREE.Vector3();
|
|
60
|
-
const pivotPoint = new THREE.Vector3();
|
|
61
|
-
const tempVector = new THREE.Vector3();
|
|
62
|
-
const tempVector2 = new THREE.Vector3();
|
|
63
|
-
const projectedStartPoint = new THREE.Vector3();
|
|
64
|
-
const projectedEndPoint = new THREE.Vector3();
|
|
65
|
-
const plane = new THREE.Plane();
|
|
66
|
-
class URDFDragControls {
|
|
67
|
-
|
|
68
|
-
constructor(scene) {
|
|
69
|
-
|
|
70
|
-
this.enabled = true;
|
|
71
|
-
this.scene = scene;
|
|
72
|
-
this.raycaster = new THREE.Raycaster();
|
|
73
|
-
this.initialGrabPoint = new THREE.Vector3();
|
|
74
|
-
|
|
75
|
-
this.hitDistance = -1;
|
|
76
|
-
this.hovered = null;
|
|
77
|
-
this.manipulating = null;
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
update() {
|
|
82
|
-
|
|
83
|
-
const {
|
|
84
|
-
raycaster,
|
|
85
|
-
hovered,
|
|
86
|
-
manipulating,
|
|
87
|
-
scene,
|
|
88
|
-
} = this;
|
|
89
|
-
|
|
90
|
-
if (manipulating) {
|
|
91
|
-
|
|
92
|
-
return;
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
let hoveredJoint = null;
|
|
97
|
-
const intersections = raycaster.intersectObject(scene, true);
|
|
98
|
-
if (intersections.length !== 0) {
|
|
99
|
-
|
|
100
|
-
const hit = intersections[0];
|
|
101
|
-
this.hitDistance = hit.distance;
|
|
102
|
-
hoveredJoint = findNearestJoint(hit.object);
|
|
103
|
-
this.initialGrabPoint.copy(hit.point);
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
if (hoveredJoint !== hovered) {
|
|
108
|
-
|
|
109
|
-
if (hovered) {
|
|
110
|
-
|
|
111
|
-
this.onUnhover(hovered);
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
this.hovered = hoveredJoint;
|
|
116
|
-
|
|
117
|
-
if (hoveredJoint) {
|
|
118
|
-
|
|
119
|
-
this.onHover(hoveredJoint);
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
updateJoint(joint, angle) {
|
|
128
|
-
|
|
129
|
-
joint.setJointValue(angle);
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
onDragStart(joint) {
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
onDragEnd(joint) {
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
onHover(joint) {
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
onUnhover(joint) {
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
150
|
-
|
|
151
|
-
// set up the plane
|
|
152
|
-
tempVector
|
|
153
|
-
.copy(joint.axis)
|
|
154
|
-
.transformDirection(joint.matrixWorld)
|
|
155
|
-
.normalize();
|
|
156
|
-
pivotPoint
|
|
157
|
-
.set(0, 0, 0)
|
|
158
|
-
.applyMatrix4(joint.matrixWorld);
|
|
159
|
-
plane
|
|
160
|
-
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
161
|
-
|
|
162
|
-
// project the drag points onto the plane
|
|
163
|
-
plane.projectPoint(startPoint, projectedStartPoint);
|
|
164
|
-
plane.projectPoint(endPoint, projectedEndPoint);
|
|
165
|
-
|
|
166
|
-
// get the directions relative to the pivot
|
|
167
|
-
projectedStartPoint.sub(pivotPoint);
|
|
168
|
-
projectedEndPoint.sub(pivotPoint);
|
|
169
|
-
|
|
170
|
-
tempVector.crossVectors(projectedStartPoint, projectedEndPoint);
|
|
171
|
-
|
|
172
|
-
const direction = Math.sign(tempVector.dot(plane.normal));
|
|
173
|
-
return direction * projectedEndPoint.angleTo(projectedStartPoint);
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
getPrismaticDelta(joint, startPoint, endPoint) {
|
|
178
|
-
|
|
179
|
-
tempVector.subVectors(endPoint, startPoint);
|
|
180
|
-
plane
|
|
181
|
-
.normal
|
|
182
|
-
.copy(joint.axis)
|
|
183
|
-
.transformDirection(joint.parent.matrixWorld)
|
|
184
|
-
.normalize();
|
|
185
|
-
|
|
186
|
-
return tempVector.dot(plane.normal);
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
moveRay(toRay) {
|
|
191
|
-
|
|
192
|
-
const { raycaster, hitDistance, manipulating } = this;
|
|
193
|
-
const { ray } = raycaster;
|
|
194
|
-
|
|
195
|
-
if (manipulating) {
|
|
196
|
-
|
|
197
|
-
ray.at(hitDistance, prevHitPoint);
|
|
198
|
-
toRay.at(hitDistance, newHitPoint);
|
|
199
|
-
|
|
200
|
-
let delta = 0;
|
|
201
|
-
if (manipulating.jointType === 'revolute' || manipulating.jointType === 'continuous') {
|
|
202
|
-
|
|
203
|
-
delta = this.getRevoluteDelta(manipulating, prevHitPoint, newHitPoint);
|
|
204
|
-
|
|
205
|
-
} else if (manipulating.jointType === 'prismatic') {
|
|
206
|
-
|
|
207
|
-
delta = this.getPrismaticDelta(manipulating, prevHitPoint, newHitPoint);
|
|
208
|
-
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
if (delta) {
|
|
212
|
-
|
|
213
|
-
this.updateJoint(manipulating, manipulating.angle + delta);
|
|
214
|
-
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
this.raycaster.ray.copy(toRay);
|
|
220
|
-
this.update();
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
setGrabbed(grabbed) {
|
|
225
|
-
|
|
226
|
-
const { hovered, manipulating } = this;
|
|
227
|
-
|
|
228
|
-
if (grabbed) {
|
|
229
|
-
|
|
230
|
-
if (manipulating !== null || hovered === null) {
|
|
231
|
-
|
|
232
|
-
return;
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
this.manipulating = hovered;
|
|
237
|
-
this.onDragStart(hovered);
|
|
238
|
-
|
|
239
|
-
} else {
|
|
240
|
-
|
|
241
|
-
if (this.manipulating === null) {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
this.onDragEnd(this.manipulating);
|
|
246
|
-
this.manipulating = null;
|
|
247
|
-
this.update();
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
class PointerURDFDragControls extends URDFDragControls {
|
|
256
|
-
|
|
257
|
-
constructor(scene, camera, domElement) {
|
|
258
|
-
|
|
259
|
-
super(scene);
|
|
260
|
-
this.camera = camera;
|
|
261
|
-
this.domElement = domElement;
|
|
262
|
-
|
|
263
|
-
const raycaster = new THREE.Raycaster();
|
|
264
|
-
const mouse = new THREE.Vector2();
|
|
265
|
-
|
|
266
|
-
function updateMouse(e) {
|
|
267
|
-
|
|
268
|
-
mouse.x = ((e.pageX - domElement.offsetLeft) / domElement.offsetWidth) * 2 - 1;
|
|
269
|
-
mouse.y = -((e.pageY - domElement.offsetTop) / domElement.offsetHeight) * 2 + 1;
|
|
270
|
-
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
this._mouseDown = e => {
|
|
274
|
-
|
|
275
|
-
updateMouse(e);
|
|
276
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
277
|
-
this.moveRay(raycaster.ray);
|
|
278
|
-
this.setGrabbed(true);
|
|
279
|
-
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
this._mouseMove = e => {
|
|
283
|
-
|
|
284
|
-
updateMouse(e);
|
|
285
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
286
|
-
this.moveRay(raycaster.ray);
|
|
287
|
-
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
this._mouseUp = e => {
|
|
291
|
-
|
|
292
|
-
updateMouse(e);
|
|
293
|
-
raycaster.setFromCamera(mouse, this.camera);
|
|
294
|
-
this.moveRay(raycaster.ray);
|
|
295
|
-
this.setGrabbed(false);
|
|
296
|
-
|
|
297
|
-
};
|
|
298
|
-
|
|
299
|
-
domElement.addEventListener('mousedown', this._mouseDown);
|
|
300
|
-
domElement.addEventListener('mousemove', this._mouseMove);
|
|
301
|
-
domElement.addEventListener('mouseup', this._mouseUp);
|
|
302
|
-
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
306
|
-
|
|
307
|
-
const { camera, initialGrabPoint } = this;
|
|
308
|
-
|
|
309
|
-
// set up the plane
|
|
310
|
-
tempVector
|
|
311
|
-
.copy(joint.axis)
|
|
312
|
-
.transformDirection(joint.matrixWorld)
|
|
313
|
-
.normalize();
|
|
314
|
-
pivotPoint
|
|
315
|
-
.set(0, 0, 0)
|
|
316
|
-
.applyMatrix4(joint.matrixWorld);
|
|
317
|
-
plane
|
|
318
|
-
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
319
|
-
|
|
320
|
-
tempVector
|
|
321
|
-
.copy(camera.position)
|
|
322
|
-
.sub(initialGrabPoint)
|
|
323
|
-
.normalize();
|
|
324
|
-
|
|
325
|
-
// if looking into the plane of rotation
|
|
326
|
-
if (Math.abs(tempVector.dot(plane.normal)) > 0.3) {
|
|
327
|
-
|
|
328
|
-
return super.getRevoluteDelta(joint, startPoint, endPoint);
|
|
329
|
-
|
|
330
|
-
} else {
|
|
331
|
-
|
|
332
|
-
// get the up direction
|
|
333
|
-
tempVector.set(0, 1, 0).transformDirection(camera.matrixWorld);
|
|
334
|
-
|
|
335
|
-
// get points projected onto the plane of rotation
|
|
336
|
-
plane.projectPoint(startPoint, projectedStartPoint);
|
|
337
|
-
plane.projectPoint(endPoint, projectedEndPoint);
|
|
338
|
-
|
|
339
|
-
tempVector.set(0, 0, -1).transformDirection(camera.matrixWorld);
|
|
340
|
-
tempVector.cross(plane.normal);
|
|
341
|
-
tempVector2.subVectors(endPoint, startPoint);
|
|
342
|
-
|
|
343
|
-
return tempVector.dot(tempVector2);
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
dispose() {
|
|
350
|
-
|
|
351
|
-
const { domElement } = this;
|
|
352
|
-
domElement.removeEventListener('mousedown', this._mouseDown);
|
|
353
|
-
domElement.removeEventListener('mousemove', this._mouseMove);
|
|
354
|
-
domElement.removeEventListener('mouseup', this._mouseUp);
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
|
|
32
|
+
// Find the nearest parent that is a joint
|
|
33
|
+
function isJoint(j) {
|
|
34
|
+
|
|
35
|
+
return j.isURDFJoint && j.jointType !== 'fixed';
|
|
36
|
+
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function findNearestJoint(child) {
|
|
40
|
+
|
|
41
|
+
let curr = child;
|
|
42
|
+
while (curr) {
|
|
43
|
+
|
|
44
|
+
if (isJoint(curr)) {
|
|
45
|
+
|
|
46
|
+
return curr;
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
curr = curr.parent;
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return curr;
|
|
55
|
+
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const prevHitPoint = new THREE.Vector3();
|
|
59
|
+
const newHitPoint = new THREE.Vector3();
|
|
60
|
+
const pivotPoint = new THREE.Vector3();
|
|
61
|
+
const tempVector = new THREE.Vector3();
|
|
62
|
+
const tempVector2 = new THREE.Vector3();
|
|
63
|
+
const projectedStartPoint = new THREE.Vector3();
|
|
64
|
+
const projectedEndPoint = new THREE.Vector3();
|
|
65
|
+
const plane = new THREE.Plane();
|
|
66
|
+
class URDFDragControls {
|
|
67
|
+
|
|
68
|
+
constructor(scene) {
|
|
69
|
+
|
|
70
|
+
this.enabled = true;
|
|
71
|
+
this.scene = scene;
|
|
72
|
+
this.raycaster = new THREE.Raycaster();
|
|
73
|
+
this.initialGrabPoint = new THREE.Vector3();
|
|
74
|
+
|
|
75
|
+
this.hitDistance = -1;
|
|
76
|
+
this.hovered = null;
|
|
77
|
+
this.manipulating = null;
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
update() {
|
|
82
|
+
|
|
83
|
+
const {
|
|
84
|
+
raycaster,
|
|
85
|
+
hovered,
|
|
86
|
+
manipulating,
|
|
87
|
+
scene,
|
|
88
|
+
} = this;
|
|
89
|
+
|
|
90
|
+
if (manipulating) {
|
|
91
|
+
|
|
92
|
+
return;
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
let hoveredJoint = null;
|
|
97
|
+
const intersections = raycaster.intersectObject(scene, true);
|
|
98
|
+
if (intersections.length !== 0) {
|
|
99
|
+
|
|
100
|
+
const hit = intersections[0];
|
|
101
|
+
this.hitDistance = hit.distance;
|
|
102
|
+
hoveredJoint = findNearestJoint(hit.object);
|
|
103
|
+
this.initialGrabPoint.copy(hit.point);
|
|
104
|
+
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (hoveredJoint !== hovered) {
|
|
108
|
+
|
|
109
|
+
if (hovered) {
|
|
110
|
+
|
|
111
|
+
this.onUnhover(hovered);
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
this.hovered = hoveredJoint;
|
|
116
|
+
|
|
117
|
+
if (hoveredJoint) {
|
|
118
|
+
|
|
119
|
+
this.onHover(hoveredJoint);
|
|
120
|
+
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
updateJoint(joint, angle) {
|
|
128
|
+
|
|
129
|
+
joint.setJointValue(angle);
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
onDragStart(joint) {
|
|
134
|
+
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
onDragEnd(joint) {
|
|
138
|
+
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
onHover(joint) {
|
|
142
|
+
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
onUnhover(joint) {
|
|
146
|
+
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
150
|
+
|
|
151
|
+
// set up the plane
|
|
152
|
+
tempVector
|
|
153
|
+
.copy(joint.axis)
|
|
154
|
+
.transformDirection(joint.matrixWorld)
|
|
155
|
+
.normalize();
|
|
156
|
+
pivotPoint
|
|
157
|
+
.set(0, 0, 0)
|
|
158
|
+
.applyMatrix4(joint.matrixWorld);
|
|
159
|
+
plane
|
|
160
|
+
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
161
|
+
|
|
162
|
+
// project the drag points onto the plane
|
|
163
|
+
plane.projectPoint(startPoint, projectedStartPoint);
|
|
164
|
+
plane.projectPoint(endPoint, projectedEndPoint);
|
|
165
|
+
|
|
166
|
+
// get the directions relative to the pivot
|
|
167
|
+
projectedStartPoint.sub(pivotPoint);
|
|
168
|
+
projectedEndPoint.sub(pivotPoint);
|
|
169
|
+
|
|
170
|
+
tempVector.crossVectors(projectedStartPoint, projectedEndPoint);
|
|
171
|
+
|
|
172
|
+
const direction = Math.sign(tempVector.dot(plane.normal));
|
|
173
|
+
return direction * projectedEndPoint.angleTo(projectedStartPoint);
|
|
174
|
+
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
getPrismaticDelta(joint, startPoint, endPoint) {
|
|
178
|
+
|
|
179
|
+
tempVector.subVectors(endPoint, startPoint);
|
|
180
|
+
plane
|
|
181
|
+
.normal
|
|
182
|
+
.copy(joint.axis)
|
|
183
|
+
.transformDirection(joint.parent.matrixWorld)
|
|
184
|
+
.normalize();
|
|
185
|
+
|
|
186
|
+
return tempVector.dot(plane.normal);
|
|
187
|
+
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
moveRay(toRay) {
|
|
191
|
+
|
|
192
|
+
const { raycaster, hitDistance, manipulating } = this;
|
|
193
|
+
const { ray } = raycaster;
|
|
194
|
+
|
|
195
|
+
if (manipulating) {
|
|
196
|
+
|
|
197
|
+
ray.at(hitDistance, prevHitPoint);
|
|
198
|
+
toRay.at(hitDistance, newHitPoint);
|
|
199
|
+
|
|
200
|
+
let delta = 0;
|
|
201
|
+
if (manipulating.jointType === 'revolute' || manipulating.jointType === 'continuous') {
|
|
202
|
+
|
|
203
|
+
delta = this.getRevoluteDelta(manipulating, prevHitPoint, newHitPoint);
|
|
204
|
+
|
|
205
|
+
} else if (manipulating.jointType === 'prismatic') {
|
|
206
|
+
|
|
207
|
+
delta = this.getPrismaticDelta(manipulating, prevHitPoint, newHitPoint);
|
|
208
|
+
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (delta) {
|
|
212
|
+
|
|
213
|
+
this.updateJoint(manipulating, manipulating.angle + delta);
|
|
214
|
+
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
this.raycaster.ray.copy(toRay);
|
|
220
|
+
this.update();
|
|
221
|
+
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
setGrabbed(grabbed) {
|
|
225
|
+
|
|
226
|
+
const { hovered, manipulating } = this;
|
|
227
|
+
|
|
228
|
+
if (grabbed) {
|
|
229
|
+
|
|
230
|
+
if (manipulating !== null || hovered === null) {
|
|
231
|
+
|
|
232
|
+
return;
|
|
233
|
+
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
this.manipulating = hovered;
|
|
237
|
+
this.onDragStart(hovered);
|
|
238
|
+
|
|
239
|
+
} else {
|
|
240
|
+
|
|
241
|
+
if (this.manipulating === null) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.onDragEnd(this.manipulating);
|
|
246
|
+
this.manipulating = null;
|
|
247
|
+
this.update();
|
|
248
|
+
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
}
|
|
252
|
+
|
|
358
253
|
}
|
|
359
254
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
this.
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
this.
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
255
|
+
class PointerURDFDragControls extends URDFDragControls {
|
|
256
|
+
|
|
257
|
+
constructor(scene, camera, domElement) {
|
|
258
|
+
|
|
259
|
+
super(scene);
|
|
260
|
+
this.camera = camera;
|
|
261
|
+
this.domElement = domElement;
|
|
262
|
+
|
|
263
|
+
const raycaster = new THREE.Raycaster();
|
|
264
|
+
const mouse = new THREE.Vector2();
|
|
265
|
+
|
|
266
|
+
function updateMouse(e) {
|
|
267
|
+
|
|
268
|
+
mouse.x = ((e.pageX - domElement.offsetLeft) / domElement.offsetWidth) * 2 - 1;
|
|
269
|
+
mouse.y = -((e.pageY - domElement.offsetTop) / domElement.offsetHeight) * 2 + 1;
|
|
270
|
+
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
this._mouseDown = e => {
|
|
274
|
+
|
|
275
|
+
updateMouse(e);
|
|
276
|
+
raycaster.setFromCamera(mouse, this.camera);
|
|
277
|
+
this.moveRay(raycaster.ray);
|
|
278
|
+
this.setGrabbed(true);
|
|
279
|
+
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
this._mouseMove = e => {
|
|
283
|
+
|
|
284
|
+
updateMouse(e);
|
|
285
|
+
raycaster.setFromCamera(mouse, this.camera);
|
|
286
|
+
this.moveRay(raycaster.ray);
|
|
287
|
+
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
this._mouseUp = e => {
|
|
291
|
+
|
|
292
|
+
updateMouse(e);
|
|
293
|
+
raycaster.setFromCamera(mouse, this.camera);
|
|
294
|
+
this.moveRay(raycaster.ray);
|
|
295
|
+
this.setGrabbed(false);
|
|
296
|
+
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
domElement.addEventListener('mousedown', this._mouseDown);
|
|
300
|
+
domElement.addEventListener('mousemove', this._mouseMove);
|
|
301
|
+
domElement.addEventListener('mouseup', this._mouseUp);
|
|
302
|
+
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
getRevoluteDelta(joint, startPoint, endPoint) {
|
|
306
|
+
|
|
307
|
+
const { camera, initialGrabPoint } = this;
|
|
308
|
+
|
|
309
|
+
// set up the plane
|
|
310
|
+
tempVector
|
|
311
|
+
.copy(joint.axis)
|
|
312
|
+
.transformDirection(joint.matrixWorld)
|
|
313
|
+
.normalize();
|
|
314
|
+
pivotPoint
|
|
315
|
+
.set(0, 0, 0)
|
|
316
|
+
.applyMatrix4(joint.matrixWorld);
|
|
317
|
+
plane
|
|
318
|
+
.setFromNormalAndCoplanarPoint(tempVector, pivotPoint);
|
|
319
|
+
|
|
320
|
+
tempVector
|
|
321
|
+
.copy(camera.position)
|
|
322
|
+
.sub(initialGrabPoint)
|
|
323
|
+
.normalize();
|
|
324
|
+
|
|
325
|
+
// if looking into the plane of rotation
|
|
326
|
+
if (Math.abs(tempVector.dot(plane.normal)) > 0.3) {
|
|
327
|
+
|
|
328
|
+
return super.getRevoluteDelta(joint, startPoint, endPoint);
|
|
329
|
+
|
|
330
|
+
} else {
|
|
331
|
+
|
|
332
|
+
// get the up direction
|
|
333
|
+
tempVector.set(0, 1, 0).transformDirection(camera.matrixWorld);
|
|
334
|
+
|
|
335
|
+
// get points projected onto the plane of rotation
|
|
336
|
+
plane.projectPoint(startPoint, projectedStartPoint);
|
|
337
|
+
plane.projectPoint(endPoint, projectedEndPoint);
|
|
338
|
+
|
|
339
|
+
tempVector.set(0, 0, -1).transformDirection(camera.matrixWorld);
|
|
340
|
+
tempVector.cross(plane.normal);
|
|
341
|
+
tempVector2.subVectors(endPoint, startPoint);
|
|
342
|
+
|
|
343
|
+
return tempVector.dot(tempVector2);
|
|
344
|
+
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
dispose() {
|
|
350
|
+
|
|
351
|
+
const { domElement } = this;
|
|
352
|
+
domElement.removeEventListener('mousedown', this._mouseDown);
|
|
353
|
+
domElement.removeEventListener('mousemove', this._mouseMove);
|
|
354
|
+
domElement.removeEventListener('mouseup', this._mouseUp);
|
|
355
|
+
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// urdf-manipulator element
|
|
361
|
+
// Displays a URDF model that can be manipulated with the mouse
|
|
362
|
+
|
|
363
|
+
// Events
|
|
364
|
+
// joint-mouseover: Fired when a joint is hovered over
|
|
365
|
+
// joint-mouseout: Fired when a joint is no longer hovered over
|
|
366
|
+
// manipulate-start: Fires when a joint is manipulated
|
|
367
|
+
// manipulate-end: Fires when a joint is done being manipulated
|
|
368
|
+
class URDFManipulator extends URDFViewer__default['default'] {
|
|
369
|
+
|
|
370
|
+
static get observedAttributes() {
|
|
371
|
+
|
|
372
|
+
return ['highlight-color', ...super.observedAttributes];
|
|
373
|
+
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
get disableDragging() { return this.hasAttribute('disable-dragging'); }
|
|
377
|
+
set disableDragging(val) { val ? this.setAttribute('disable-dragging', !!val) : this.removeAttribute('disable-dragging'); }
|
|
378
|
+
|
|
379
|
+
get highlightColor() { return this.getAttribute('highlight-color') || '#FFFFFF'; }
|
|
380
|
+
set highlightColor(val) { val ? this.setAttribute('highlight-color', val) : this.removeAttribute('highlight-color'); }
|
|
381
|
+
|
|
382
|
+
constructor(...args) {
|
|
383
|
+
|
|
384
|
+
super(...args);
|
|
385
|
+
|
|
386
|
+
// The highlight material
|
|
387
|
+
this.highlightMaterial =
|
|
388
|
+
new THREE__namespace.MeshPhongMaterial({
|
|
389
|
+
shininess: 10,
|
|
390
|
+
color: this.highlightColor,
|
|
391
|
+
emissive: this.highlightColor,
|
|
392
|
+
emissiveIntensity: 0.25,
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
const isJoint = j => {
|
|
396
|
+
|
|
397
|
+
return j.isURDFJoint && j.jointType !== 'fixed';
|
|
398
|
+
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// Highlight the link geometry under a joint
|
|
402
|
+
const highlightLinkGeometry = (m, revert) => {
|
|
403
|
+
|
|
404
|
+
const traverse = c => {
|
|
405
|
+
|
|
406
|
+
// Set or revert the highlight color
|
|
407
|
+
if (c.type === 'Mesh') {
|
|
408
|
+
|
|
409
|
+
if (revert) {
|
|
410
|
+
|
|
411
|
+
c.material = c.__origMaterial;
|
|
412
|
+
delete c.__origMaterial;
|
|
413
|
+
|
|
414
|
+
} else {
|
|
415
|
+
|
|
416
|
+
c.__origMaterial = c.material;
|
|
417
|
+
c.material = this.highlightMaterial;
|
|
418
|
+
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Look into the children and stop if the next child is
|
|
424
|
+
// another joint
|
|
425
|
+
if (c === m || !isJoint(c)) {
|
|
426
|
+
|
|
427
|
+
for (let i = 0; i < c.children.length; i++) {
|
|
428
|
+
|
|
429
|
+
const child = c.children[i];
|
|
430
|
+
if (!child.isURDFCollider) {
|
|
431
|
+
|
|
432
|
+
traverse(c.children[i]);
|
|
433
|
+
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
};
|
|
441
|
+
|
|
442
|
+
traverse(m);
|
|
443
|
+
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
const el = this.renderer.domElement;
|
|
447
|
+
|
|
448
|
+
const dragControls = new PointerURDFDragControls(this.scene, this.camera, el);
|
|
449
|
+
dragControls.onDragStart = joint => {
|
|
450
|
+
|
|
451
|
+
this.dispatchEvent(new CustomEvent('manipulate-start', { bubbles: true, cancelable: true, detail: joint.name }));
|
|
452
|
+
this.controls.enabled = false;
|
|
453
|
+
this.redraw();
|
|
454
|
+
|
|
455
|
+
};
|
|
456
|
+
dragControls.onDragEnd = joint => {
|
|
457
|
+
|
|
458
|
+
this.dispatchEvent(new CustomEvent('manipulate-end', { bubbles: true, cancelable: true, detail: joint.name }));
|
|
459
|
+
this.controls.enabled = true;
|
|
460
|
+
this.redraw();
|
|
461
|
+
|
|
462
|
+
};
|
|
463
|
+
dragControls.updateJoint = (joint, angle) => {
|
|
464
|
+
|
|
465
|
+
this.setJointValue(joint.name, angle);
|
|
466
|
+
|
|
467
|
+
};
|
|
468
|
+
dragControls.onHover = joint => {
|
|
469
|
+
|
|
470
|
+
highlightLinkGeometry(joint, false);
|
|
471
|
+
this.dispatchEvent(new CustomEvent('joint-mouseover', { bubbles: true, cancelable: true, detail: joint.name }));
|
|
472
|
+
this.redraw();
|
|
473
|
+
|
|
474
|
+
};
|
|
475
|
+
dragControls.onUnhover = joint => {
|
|
476
|
+
|
|
477
|
+
highlightLinkGeometry(joint, true);
|
|
478
|
+
this.dispatchEvent(new CustomEvent('joint-mouseout', { bubbles: true, cancelable: true, detail: joint.name }));
|
|
479
|
+
this.redraw();
|
|
480
|
+
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
this.dragControls = dragControls;
|
|
484
|
+
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
disconnectedCallback() {
|
|
488
|
+
|
|
489
|
+
super.disconnectedCallback();
|
|
490
|
+
this.dragControls.dispose();
|
|
491
|
+
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
attributeChangedCallback(attr, oldval, newval) {
|
|
495
|
+
|
|
496
|
+
super.attributeChangedCallback(attr, oldval, newval);
|
|
497
|
+
|
|
498
|
+
switch (attr) {
|
|
499
|
+
|
|
500
|
+
case 'highlight-color':
|
|
501
|
+
this.highlightMaterial.color.set(this.highlightColor);
|
|
502
|
+
this.highlightMaterial.emissive.set(this.highlightColor);
|
|
503
|
+
break;
|
|
504
|
+
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
}
|
|
508
|
+
|
|
504
509
|
};
|
|
505
510
|
|
|
506
511
|
return URDFManipulator;
|