urdf-loader-babylonjs 0.1.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.
@@ -0,0 +1,614 @@
1
+ (function (global, factory) {
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@babylonjs/core'), require('./URDFLoader.js')) :
3
+ typeof define === 'function' && define.amd ? define(['@babylonjs/core', './URDFLoader'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.URDFViewer = factory(global.BABYLON, global.URDFLoader));
5
+ })(this, (function (core, URDFLoader) { 'use strict';
6
+
7
+ // urdf-viewer element
8
+ // Loads and displays a 3D view of a URDF-formatted robot
9
+
10
+ // Events
11
+ // urdf-change: Fires when the URDF has finished loading and getting processed
12
+ // urdf-processed: Fires when the URDF has finished loading and getting processed
13
+ // geometry-loaded: Fires when all the geometry has been fully loaded
14
+ // ignore-limits-change: Fires when the 'ignore-limits' attribute changes
15
+ // angle-change: Fires when an angle changes
16
+ class URDFViewer extends HTMLElement {
17
+
18
+ static get observedAttributes() {
19
+
20
+ return ['package', 'urdf', 'up', 'display-shadow', 'ambient-color', 'ignore-limits', 'show-collision'];
21
+
22
+ }
23
+
24
+ get package() { return this.getAttribute('package') || ''; }
25
+ set package(val) { this.setAttribute('package', val); }
26
+
27
+ get urdf() { return this.getAttribute('urdf') || ''; }
28
+ set urdf(val) { this.setAttribute('urdf', val); }
29
+
30
+ get ignoreLimits() { return this.hasAttribute('ignore-limits') || false; }
31
+ set ignoreLimits(val) { val ? this.setAttribute('ignore-limits', val) : this.removeAttribute('ignore-limits'); }
32
+
33
+ get up() { return this.getAttribute('up') || '+Z'; }
34
+ set up(val) { this.setAttribute('up', val); }
35
+
36
+ get displayShadow() { return this.hasAttribute('display-shadow') || false; }
37
+ set displayShadow(val) { val ? this.setAttribute('display-shadow', '') : this.removeAttribute('display-shadow'); }
38
+
39
+ get ambientColor() { return this.getAttribute('ambient-color') || '#8ea0a8'; }
40
+ set ambientColor(val) { val ? this.setAttribute('ambient-color', val) : this.removeAttribute('ambient-color'); }
41
+
42
+ get autoRedraw() { return this.hasAttribute('auto-redraw') || false; }
43
+ set autoRedraw(val) { val ? this.setAttribute('auto-redraw', true) : this.removeAttribute('auto-redraw'); }
44
+
45
+ get noAutoRecenter() { return this.hasAttribute('no-auto-recenter') || false; }
46
+ set noAutoRecenter(val) { val ? this.setAttribute('no-auto-recenter', true) : this.removeAttribute('no-auto-recenter'); }
47
+
48
+ get showCollision() { return this.hasAttribute('show-collision') || false; }
49
+ set showCollision(val) { val ? this.setAttribute('show-collision', true) : this.removeAttribute('show-collision'); }
50
+
51
+ get jointValues() {
52
+
53
+ const values = {};
54
+ if (this.robot) {
55
+
56
+ for (const name in this.robot.joints) {
57
+
58
+ const joint = this.robot.joints[name];
59
+ values[name] = joint.jointValue.length === 1 ? joint.angle : [...joint.jointValue];
60
+
61
+ }
62
+
63
+ }
64
+
65
+ return values;
66
+
67
+ }
68
+ set jointValues(val) { this.setJointValues(val); }
69
+
70
+ get angles() {
71
+
72
+ return this.jointValues;
73
+
74
+ }
75
+ set angles(v) {
76
+
77
+ this.jointValues = v;
78
+
79
+ }
80
+
81
+ /* Lifecycle Functions */
82
+ constructor() {
83
+
84
+ super();
85
+
86
+ this._requestId = 0;
87
+ this._dirty = false;
88
+ this._loadScheduled = false;
89
+ this.robot = null;
90
+ this.loadMeshFunc = null;
91
+ this.urlModifierFunc = null;
92
+
93
+ // Create a canvas element for Babylon.js
94
+ const canvas = document.createElement('canvas');
95
+ this._canvas = canvas;
96
+
97
+ // Engine setup
98
+ const engine = new core.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });
99
+ this.engine = engine;
100
+
101
+ // Scene setup
102
+ const scene = new core.Scene(engine);
103
+ scene.useRightHandedSystem = true;
104
+ scene.clearColor = new core.Color4(0, 0, 0, 0);
105
+
106
+ // Ambient light
107
+ const ambientLight = new core.HemisphericLight('ambientLight', new core.Vector3(0, 1, 0), scene);
108
+ const c3 = this._parseColor(this.ambientColor);
109
+ ambientLight.diffuse = c3;
110
+ ambientLight.groundColor = core.Color3.Lerp(core.Color3.Black(), c3, 0.5);
111
+ ambientLight.intensity = 0.5;
112
+
113
+ // Directional light
114
+ const dirLight = new core.DirectionalLight('dirLight', new core.Vector3(-4, -10, -1), scene);
115
+ dirLight.intensity = Math.PI;
116
+ dirLight.position = new core.Vector3(4, 10, 1);
117
+
118
+ // Shadow generator
119
+ this._shadowGenerator = new core.ShadowGenerator(2048, dirLight);
120
+ this._shadowGenerator.useBlurExponentialShadowMap = true;
121
+ this._shadowGenerator.bias = 0.001;
122
+
123
+ // Camera setup (ArcRotateCamera has built-in orbit controls)
124
+ const camera = new core.ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 3, 10, core.Vector3.Zero(), scene);
125
+ camera.minZ = 0.1;
126
+ camera.maxZ = 1000;
127
+ camera.lowerRadiusLimit = 0.25;
128
+ camera.upperRadiusLimit = 50;
129
+ camera.wheelPrecision = 5;
130
+ camera.panningSensibility = 50;
131
+ camera.attachControl(canvas, true);
132
+
133
+ // World node for up-axis rotation
134
+ const world = new core.TransformNode('world', scene);
135
+ world.rotationQuaternion = new core.Quaternion();
136
+
137
+ // Ground plane for shadows
138
+ const ground = core.MeshBuilder.CreateGround('ground', { width: 400, height: 400 }, scene);
139
+ const groundMaterial = new core.StandardMaterial('groundMat', scene);
140
+ groundMaterial.diffuseColor = core.Color3.Black();
141
+ groundMaterial.specularColor = core.Color3.Black();
142
+ groundMaterial.alpha = 0.25;
143
+ ground.material = groundMaterial;
144
+ ground.receiveShadows = true;
145
+ ground.position.y = -0.5;
146
+ ground.isPickable = false;
147
+
148
+ this.scene = scene;
149
+ this.babylonScene = scene;
150
+ this.world = world;
151
+ this.camera = camera;
152
+ this.controls = camera; // camera is also the controls in Babylon.js
153
+ this.ground = ground;
154
+ this.directionalLight = dirLight;
155
+ this.ambientLight = ambientLight;
156
+
157
+ this._setUp(this.up);
158
+
159
+ this._collisionMaterial = new core.StandardMaterial('collisionMat', scene);
160
+ this._collisionMaterial.diffuseColor = new core.Color3(1.0, 0.745, 0.22);
161
+ this._collisionMaterial.alpha = 0.35;
162
+ this._collisionMaterial.transparencyMode = core.Material.MATERIAL_ALPHABLEND;
163
+
164
+ // Render loop
165
+ engine.runRenderLoop(() => {
166
+
167
+ if (this.parentNode) {
168
+
169
+ this.updateSize();
170
+
171
+ if (this._dirty || this.autoRedraw) {
172
+
173
+ if (!this.noAutoRecenter) {
174
+
175
+ this._updateEnvironment();
176
+ }
177
+
178
+ this._dirty = false;
179
+
180
+ }
181
+
182
+ scene.render();
183
+
184
+ }
185
+
186
+ });
187
+
188
+ }
189
+
190
+ _parseColor(colorStr) {
191
+
192
+ if (!colorStr) return new core.Color3(0.56, 0.63, 0.66);
193
+ try {
194
+
195
+ // Expand shorthand hex
196
+ if (colorStr.length === 4) {
197
+
198
+ colorStr = '#' + colorStr[1] + colorStr[1] + colorStr[2] + colorStr[2] + colorStr[3] + colorStr[3];
199
+
200
+ }
201
+ return core.Color3.FromHexString(colorStr);
202
+
203
+ } catch {
204
+
205
+ return new core.Color3(0.56, 0.63, 0.66);
206
+
207
+ }
208
+
209
+ }
210
+
211
+ connectedCallback() {
212
+
213
+ // Add our initialize styles for the element if they haven't
214
+ // been added yet
215
+ if (!this.constructor._styletag) {
216
+
217
+ const styletag = document.createElement('style');
218
+ styletag.innerHTML =
219
+ `
220
+ ${ this.tagName } { display: block; }
221
+ ${ this.tagName } canvas {
222
+ width: 100%;
223
+ height: 100%;
224
+ }
225
+ `;
226
+ document.head.appendChild(styletag);
227
+ this.constructor._styletag = styletag;
228
+
229
+ }
230
+
231
+ // add the canvas
232
+ if (this.childElementCount === 0) {
233
+
234
+ this.appendChild(this._canvas);
235
+
236
+ }
237
+
238
+ this.updateSize();
239
+ requestAnimationFrame(() => this.updateSize());
240
+
241
+ }
242
+
243
+ disconnectedCallback() {
244
+
245
+ this.engine.stopRenderLoop();
246
+
247
+ }
248
+
249
+ attributeChangedCallback(attr, oldval, newval) {
250
+
251
+ this._updateCollisionVisibility();
252
+ if (!this.noAutoRecenter) {
253
+ this.recenter();
254
+ }
255
+
256
+ switch (attr) {
257
+
258
+ case 'package':
259
+ case 'urdf': {
260
+
261
+ this._scheduleLoad();
262
+ break;
263
+
264
+ }
265
+
266
+ case 'up': {
267
+
268
+ this._setUp(this.up);
269
+ break;
270
+
271
+ }
272
+
273
+ case 'ambient-color': {
274
+
275
+ const c3 = this._parseColor(this.ambientColor);
276
+ this.ambientLight.diffuse = c3;
277
+ this.ambientLight.groundColor = core.Color3.Lerp(core.Color3.Black(), c3, 0.5);
278
+ break;
279
+
280
+ }
281
+
282
+ case 'ignore-limits': {
283
+
284
+ this._setIgnoreLimits(this.ignoreLimits, true);
285
+ break;
286
+
287
+ }
288
+
289
+ }
290
+
291
+ }
292
+
293
+ /* Public API */
294
+ updateSize() {
295
+
296
+ const w = this.clientWidth;
297
+ const h = this.clientHeight;
298
+
299
+ if (w > 0 && h > 0) {
300
+
301
+ this._canvas.width = w * window.devicePixelRatio;
302
+ this._canvas.height = h * window.devicePixelRatio;
303
+ this.engine.resize();
304
+
305
+ }
306
+
307
+ }
308
+
309
+ redraw() {
310
+
311
+ this._dirty = true;
312
+ }
313
+
314
+ recenter() {
315
+
316
+ this._updateEnvironment();
317
+ this.redraw();
318
+
319
+ }
320
+
321
+ // Set the joint with jointName to
322
+ // angle in degrees
323
+ setJointValue(jointName, ...values) {
324
+
325
+ if (!this.robot) return;
326
+ if (!this.robot.joints[jointName]) return;
327
+
328
+ if (this.robot.joints[jointName].setJointValue(...values)) {
329
+
330
+ this.redraw();
331
+ this.dispatchEvent(new CustomEvent('angle-change', { bubbles: true, cancelable: true, detail: jointName }));
332
+
333
+ }
334
+
335
+ }
336
+
337
+ setJointValues(values) {
338
+
339
+ for (const name in values) {
340
+
341
+ if (Array.isArray(values[name])) {
342
+
343
+ this.setJointValue(name, ...values[name]);
344
+
345
+ } else {
346
+
347
+ this.setJointValue(name, values[name]);
348
+
349
+ }
350
+
351
+ }
352
+
353
+ }
354
+
355
+ /* Private Functions */
356
+ _updateEnvironment() {
357
+
358
+ const robot = this.robot;
359
+ if (!robot) return;
360
+
361
+ // Compute bounding info from visual meshes
362
+ let min = new core.Vector3(Infinity, Infinity, Infinity);
363
+ let max = new core.Vector3(-Infinity, -Infinity, -Infinity);
364
+
365
+ const processNode = (node) => {
366
+
367
+ if (node.getBoundingInfo && node instanceof core.Mesh && node.getTotalVertices() > 0) {
368
+
369
+ node.computeWorldMatrix(true);
370
+ const bi = node.getBoundingInfo();
371
+ min = core.Vector3.Minimize(min, bi.boundingBox.minimumWorld);
372
+ max = core.Vector3.Maximize(max, bi.boundingBox.maximumWorld);
373
+
374
+ }
375
+ if (node.getChildren) {
376
+
377
+ node.getChildren().forEach(processNode);
378
+
379
+ }
380
+
381
+ };
382
+
383
+ robot.traverse(c => {
384
+ if (c.isURDFVisual) {
385
+
386
+ processNode(c);
387
+
388
+ }
389
+ });
390
+
391
+ if (min.x === Infinity) return;
392
+
393
+ const center = core.Vector3.Center(min, max);
394
+ this.camera.target.y = center.y;
395
+ this.ground.position.y = min.y - 1e-3;
396
+
397
+ const dirLight = this.directionalLight;
398
+
399
+ if (this.displayShadow) {
400
+
401
+ const radius = core.Vector3.Distance(min, max) / 2;
402
+ dirLight.shadowMinZ = -radius * 3;
403
+ dirLight.shadowMaxZ = radius * 3;
404
+
405
+ }
406
+
407
+ }
408
+
409
+ _scheduleLoad() {
410
+
411
+ // if our current model is already what's being requested
412
+ // or has been loaded then early out
413
+ if (this._prevload === `${ this.package }|${ this.urdf }`) return;
414
+ this._prevload = `${ this.package }|${ this.urdf }`;
415
+
416
+ // if we're already waiting on a load then early out
417
+ if (this._loadScheduled) return;
418
+ this._loadScheduled = true;
419
+
420
+ if (this.robot) {
421
+
422
+ this.robot.traverse(c => c.dispose && c.dispose());
423
+ this.robot = null;
424
+
425
+ }
426
+
427
+ requestAnimationFrame(() => {
428
+
429
+ this._loadUrdf(this.package, this.urdf);
430
+ this._loadScheduled = false;
431
+
432
+ });
433
+
434
+ }
435
+
436
+ // Watch the package and urdf field and load the robot model.
437
+ // This should _only_ be called from _scheduleLoad because that
438
+ // ensures the that current robot has been removed
439
+ _loadUrdf(pkg, urdf) {
440
+
441
+ this.dispatchEvent(new CustomEvent('urdf-change', { bubbles: true, cancelable: true, composed: true }));
442
+
443
+ if (urdf) {
444
+
445
+ // Keep track of this request and make
446
+ // sure it doesn't get overwritten by
447
+ // a subsequent one
448
+ this._requestId++;
449
+ const requestId = this._requestId;
450
+
451
+ const updateMaterials = mesh => {
452
+
453
+ mesh.traverse(c => {
454
+
455
+ if (c instanceof core.Mesh) {
456
+
457
+ // Add to shadow generator
458
+ this._shadowGenerator.addShadowCaster(c);
459
+ c.receiveShadows = true;
460
+
461
+ }
462
+
463
+ });
464
+
465
+ };
466
+
467
+ if (pkg.includes(':') && (pkg.split(':')[1].substring(0, 2)) !== '//') {
468
+
469
+ pkg = pkg.split(',').reduce((map, value) => {
470
+
471
+ const split = value.split(/:/).filter(x => !!x);
472
+ const pkgName = split.shift().trim();
473
+ const pkgPath = split.join(':').trim();
474
+ map[pkgName] = pkgPath;
475
+
476
+ return map;
477
+
478
+ }, {});
479
+ }
480
+
481
+ let robot = null;
482
+ const loader = new URDFLoader(this.scene);
483
+ loader.packages = pkg;
484
+ if (this.loadMeshFunc) {
485
+
486
+ loader.loadMeshCb = this.loadMeshFunc;
487
+
488
+ }
489
+ loader.fetchOptions = { mode: 'cors', credentials: 'same-origin' };
490
+ loader.parseCollision = true;
491
+
492
+ loader.manager.onLoad = () => {
493
+
494
+ // If another request has come in to load a new
495
+ // robot, then ignore this one
496
+ if (this._requestId !== requestId) {
497
+
498
+ if (robot) robot.traverse(c => c.dispose && c.dispose());
499
+ return;
500
+
501
+ }
502
+
503
+ this.robot = robot;
504
+ robot.parent = this.world;
505
+ updateMaterials(robot);
506
+
507
+ this._setIgnoreLimits(this.ignoreLimits);
508
+ this._updateCollisionVisibility();
509
+
510
+ this.dispatchEvent(new CustomEvent('urdf-processed', { bubbles: true, cancelable: true, composed: true }));
511
+ this.dispatchEvent(new CustomEvent('geometry-loaded', { bubbles: true, cancelable: true, composed: true }));
512
+
513
+ this.recenter();
514
+
515
+ };
516
+
517
+ loader.load(urdf, model => robot = model);
518
+
519
+ }
520
+
521
+ }
522
+
523
+ _updateCollisionVisibility() {
524
+
525
+ const showCollision = this.showCollision;
526
+ const collisionMaterial = this._collisionMaterial;
527
+ const robot = this.robot;
528
+
529
+ if (robot === null) return;
530
+
531
+ const colliders = [];
532
+ robot.traverse(c => {
533
+
534
+ if (c.isURDFCollider) {
535
+
536
+ c.setEnabled(showCollision);
537
+ colliders.push(c);
538
+
539
+ }
540
+
541
+ });
542
+
543
+ colliders.forEach(coll => {
544
+
545
+ coll.traverse(c => {
546
+
547
+ if (c instanceof core.Mesh) {
548
+
549
+ c.isPickable = false;
550
+ c.material = collisionMaterial;
551
+
552
+ }
553
+
554
+ });
555
+
556
+ });
557
+
558
+ }
559
+
560
+ // Watch the coordinate frame and update the
561
+ // rotation of the scene to match
562
+ _setUp(up) {
563
+
564
+ if (!up) up = '+Z';
565
+ up = up.toUpperCase();
566
+ const sign = up.replace(/[^-+]/g, '')[0] || '+';
567
+ const axis = up.replace(/[^XYZ]/gi, '')[0] || 'Z';
568
+
569
+ if (!this.world) return;
570
+
571
+ const PI = Math.PI;
572
+ const HALFPI = PI / 2;
573
+
574
+ let rx = 0, rz = 0;
575
+ const ry = 0;
576
+ if (axis === 'X') { rz = sign === '+' ? HALFPI : -HALFPI; }
577
+ if (axis === 'Z') { rx = sign === '+' ? -HALFPI : HALFPI; }
578
+ if (axis === 'Y') { rx = sign === '+' ? 0 : PI; }
579
+
580
+ this.world.rotationQuaternion = core.Quaternion.RotationYawPitchRoll(ry, rx, rz);
581
+
582
+ }
583
+
584
+ // Updates the current robot's angles to ignore
585
+ // joint limits or not
586
+ _setIgnoreLimits(ignore, dispatch = false) {
587
+
588
+ if (this.robot) {
589
+
590
+ Object
591
+ .values(this.robot.joints)
592
+ .forEach(joint => {
593
+
594
+ joint.ignoreLimits = ignore;
595
+ joint.setJointValue(...joint.jointValue);
596
+
597
+ });
598
+
599
+ }
600
+
601
+ if (dispatch) {
602
+
603
+ this.dispatchEvent(new CustomEvent('ignore-limits-change', { bubbles: true, cancelable: true, composed: true }));
604
+
605
+ }
606
+
607
+ }
608
+
609
+ }
610
+
611
+ return URDFViewer;
612
+
613
+ }));
614
+ //# sourceMappingURL=urdf-viewer-element.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urdf-viewer-element.js","sources":["../src/urdf-viewer-element.js"],"sourcesContent":["import { Engine, Scene, ArcRotateCamera, HemisphericLight, DirectionalLight, ShadowGenerator, MeshBuilder, StandardMaterial, Color3, Color4, Vector3, Quaternion, Mesh, Material, TransformNode } from '@babylonjs/core';\nimport URDFLoader from './URDFLoader.js';\n\n// urdf-viewer element\n// Loads and displays a 3D view of a URDF-formatted robot\n\n// Events\n// urdf-change: Fires when the URDF has finished loading and getting processed\n// urdf-processed: Fires when the URDF has finished loading and getting processed\n// geometry-loaded: Fires when all the geometry has been fully loaded\n// ignore-limits-change: Fires when the 'ignore-limits' attribute changes\n// angle-change: Fires when an angle changes\nexport default\nclass URDFViewer extends HTMLElement {\n\n static get observedAttributes() {\n\n return ['package', 'urdf', 'up', 'display-shadow', 'ambient-color', 'ignore-limits', 'show-collision'];\n\n }\n\n get package() { return this.getAttribute('package') || ''; }\n set package(val) { this.setAttribute('package', val); }\n\n get urdf() { return this.getAttribute('urdf') || ''; }\n set urdf(val) { this.setAttribute('urdf', val); }\n\n get ignoreLimits() { return this.hasAttribute('ignore-limits') || false; }\n set ignoreLimits(val) { val ? this.setAttribute('ignore-limits', val) : this.removeAttribute('ignore-limits'); }\n\n get up() { return this.getAttribute('up') || '+Z'; }\n set up(val) { this.setAttribute('up', val); }\n\n get displayShadow() { return this.hasAttribute('display-shadow') || false; }\n set displayShadow(val) { val ? this.setAttribute('display-shadow', '') : this.removeAttribute('display-shadow'); }\n\n get ambientColor() { return this.getAttribute('ambient-color') || '#8ea0a8'; }\n set ambientColor(val) { val ? this.setAttribute('ambient-color', val) : this.removeAttribute('ambient-color'); }\n\n get autoRedraw() { return this.hasAttribute('auto-redraw') || false; }\n set autoRedraw(val) { val ? this.setAttribute('auto-redraw', true) : this.removeAttribute('auto-redraw'); }\n\n get noAutoRecenter() { return this.hasAttribute('no-auto-recenter') || false; }\n set noAutoRecenter(val) { val ? this.setAttribute('no-auto-recenter', true) : this.removeAttribute('no-auto-recenter'); }\n\n get showCollision() { return this.hasAttribute('show-collision') || false; }\n set showCollision(val) { val ? this.setAttribute('show-collision', true) : this.removeAttribute('show-collision'); }\n\n get jointValues() {\n\n const values = {};\n if (this.robot) {\n\n for (const name in this.robot.joints) {\n\n const joint = this.robot.joints[name];\n values[name] = joint.jointValue.length === 1 ? joint.angle : [...joint.jointValue];\n\n }\n\n }\n\n return values;\n\n }\n set jointValues(val) { this.setJointValues(val); }\n\n get angles() {\n\n return this.jointValues;\n\n }\n set angles(v) {\n\n this.jointValues = v;\n\n }\n\n /* Lifecycle Functions */\n constructor() {\n\n super();\n\n this._requestId = 0;\n this._dirty = false;\n this._loadScheduled = false;\n this.robot = null;\n this.loadMeshFunc = null;\n this.urlModifierFunc = null;\n\n // Create a canvas element for Babylon.js\n const canvas = document.createElement('canvas');\n this._canvas = canvas;\n\n // Engine setup\n const engine = new Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true });\n this.engine = engine;\n\n // Scene setup\n const scene = new Scene(engine);\n scene.useRightHandedSystem = true;\n scene.clearColor = new Color4(0, 0, 0, 0);\n\n // Ambient light\n const ambientLight = new HemisphericLight('ambientLight', new Vector3(0, 1, 0), scene);\n const c3 = this._parseColor(this.ambientColor);\n ambientLight.diffuse = c3;\n ambientLight.groundColor = Color3.Lerp(Color3.Black(), c3, 0.5);\n ambientLight.intensity = 0.5;\n\n // Directional light\n const dirLight = new DirectionalLight('dirLight', new Vector3(-4, -10, -1), scene);\n dirLight.intensity = Math.PI;\n dirLight.position = new Vector3(4, 10, 1);\n\n // Shadow generator\n this._shadowGenerator = new ShadowGenerator(2048, dirLight);\n this._shadowGenerator.useBlurExponentialShadowMap = true;\n this._shadowGenerator.bias = 0.001;\n\n // Camera setup (ArcRotateCamera has built-in orbit controls)\n const camera = new ArcRotateCamera('camera', -Math.PI / 2, Math.PI / 3, 10, Vector3.Zero(), scene);\n camera.minZ = 0.1;\n camera.maxZ = 1000;\n camera.lowerRadiusLimit = 0.25;\n camera.upperRadiusLimit = 50;\n camera.wheelPrecision = 5;\n camera.panningSensibility = 50;\n camera.attachControl(canvas, true);\n\n // World node for up-axis rotation\n const world = new TransformNode('world', scene);\n world.rotationQuaternion = new Quaternion();\n\n // Ground plane for shadows\n const ground = MeshBuilder.CreateGround('ground', { width: 400, height: 400 }, scene);\n const groundMaterial = new StandardMaterial('groundMat', scene);\n groundMaterial.diffuseColor = Color3.Black();\n groundMaterial.specularColor = Color3.Black();\n groundMaterial.alpha = 0.25;\n ground.material = groundMaterial;\n ground.receiveShadows = true;\n ground.position.y = -0.5;\n ground.isPickable = false;\n\n this.scene = scene;\n this.babylonScene = scene;\n this.world = world;\n this.camera = camera;\n this.controls = camera; // camera is also the controls in Babylon.js\n this.ground = ground;\n this.directionalLight = dirLight;\n this.ambientLight = ambientLight;\n\n this._setUp(this.up);\n\n this._collisionMaterial = new StandardMaterial('collisionMat', scene);\n this._collisionMaterial.diffuseColor = new Color3(1.0, 0.745, 0.22);\n this._collisionMaterial.alpha = 0.35;\n this._collisionMaterial.transparencyMode = Material.MATERIAL_ALPHABLEND;\n\n // Render loop\n engine.runRenderLoop(() => {\n\n if (this.parentNode) {\n\n this.updateSize();\n\n if (this._dirty || this.autoRedraw) {\n\n if (!this.noAutoRecenter) {\n\n this._updateEnvironment();\n }\n\n this._dirty = false;\n\n }\n\n scene.render();\n\n }\n\n });\n\n }\n\n _parseColor(colorStr) {\n\n if (!colorStr) return new Color3(0.56, 0.63, 0.66);\n try {\n\n // Expand shorthand hex\n if (colorStr.length === 4) {\n\n colorStr = '#' + colorStr[1] + colorStr[1] + colorStr[2] + colorStr[2] + colorStr[3] + colorStr[3];\n\n }\n return Color3.FromHexString(colorStr);\n\n } catch {\n\n return new Color3(0.56, 0.63, 0.66);\n\n }\n\n }\n\n connectedCallback() {\n\n // Add our initialize styles for the element if they haven't\n // been added yet\n if (!this.constructor._styletag) {\n\n const styletag = document.createElement('style');\n styletag.innerHTML =\n `\n ${ this.tagName } { display: block; }\n ${ this.tagName } canvas {\n width: 100%;\n height: 100%;\n }\n `;\n document.head.appendChild(styletag);\n this.constructor._styletag = styletag;\n\n }\n\n // add the canvas\n if (this.childElementCount === 0) {\n\n this.appendChild(this._canvas);\n\n }\n\n this.updateSize();\n requestAnimationFrame(() => this.updateSize());\n\n }\n\n disconnectedCallback() {\n\n this.engine.stopRenderLoop();\n\n }\n\n attributeChangedCallback(attr, oldval, newval) {\n\n this._updateCollisionVisibility();\n if (!this.noAutoRecenter) {\n this.recenter();\n }\n\n switch (attr) {\n\n case 'package':\n case 'urdf': {\n\n this._scheduleLoad();\n break;\n\n }\n\n case 'up': {\n\n this._setUp(this.up);\n break;\n\n }\n\n case 'ambient-color': {\n\n const c3 = this._parseColor(this.ambientColor);\n this.ambientLight.diffuse = c3;\n this.ambientLight.groundColor = Color3.Lerp(Color3.Black(), c3, 0.5);\n break;\n\n }\n\n case 'ignore-limits': {\n\n this._setIgnoreLimits(this.ignoreLimits, true);\n break;\n\n }\n\n }\n\n }\n\n /* Public API */\n updateSize() {\n\n const w = this.clientWidth;\n const h = this.clientHeight;\n\n if (w > 0 && h > 0) {\n\n this._canvas.width = w * window.devicePixelRatio;\n this._canvas.height = h * window.devicePixelRatio;\n this.engine.resize();\n\n }\n\n }\n\n redraw() {\n\n this._dirty = true;\n }\n\n recenter() {\n\n this._updateEnvironment();\n this.redraw();\n\n }\n\n // Set the joint with jointName to\n // angle in degrees\n setJointValue(jointName, ...values) {\n\n if (!this.robot) return;\n if (!this.robot.joints[jointName]) return;\n\n if (this.robot.joints[jointName].setJointValue(...values)) {\n\n this.redraw();\n this.dispatchEvent(new CustomEvent('angle-change', { bubbles: true, cancelable: true, detail: jointName }));\n\n }\n\n }\n\n setJointValues(values) {\n\n for (const name in values) {\n\n if (Array.isArray(values[name])) {\n\n this.setJointValue(name, ...values[name]);\n\n } else {\n\n this.setJointValue(name, values[name]);\n\n }\n\n }\n\n }\n\n /* Private Functions */\n _updateEnvironment() {\n\n const robot = this.robot;\n if (!robot) return;\n\n // Compute bounding info from visual meshes\n let min = new Vector3(Infinity, Infinity, Infinity);\n let max = new Vector3(-Infinity, -Infinity, -Infinity);\n\n const processNode = (node) => {\n\n if (node.getBoundingInfo && node instanceof Mesh && node.getTotalVertices() > 0) {\n\n node.computeWorldMatrix(true);\n const bi = node.getBoundingInfo();\n min = Vector3.Minimize(min, bi.boundingBox.minimumWorld);\n max = Vector3.Maximize(max, bi.boundingBox.maximumWorld);\n\n }\n if (node.getChildren) {\n\n node.getChildren().forEach(processNode);\n\n }\n\n };\n\n robot.traverse(c => {\n if (c.isURDFVisual) {\n\n processNode(c);\n\n }\n });\n\n if (min.x === Infinity) return;\n\n const center = Vector3.Center(min, max);\n this.camera.target.y = center.y;\n this.ground.position.y = min.y - 1e-3;\n\n const dirLight = this.directionalLight;\n\n if (this.displayShadow) {\n\n const radius = Vector3.Distance(min, max) / 2;\n dirLight.shadowMinZ = -radius * 3;\n dirLight.shadowMaxZ = radius * 3;\n\n }\n\n }\n\n _scheduleLoad() {\n\n // if our current model is already what's being requested\n // or has been loaded then early out\n if (this._prevload === `${ this.package }|${ this.urdf }`) return;\n this._prevload = `${ this.package }|${ this.urdf }`;\n\n // if we're already waiting on a load then early out\n if (this._loadScheduled) return;\n this._loadScheduled = true;\n\n if (this.robot) {\n\n this.robot.traverse(c => c.dispose && c.dispose());\n this.robot = null;\n\n }\n\n requestAnimationFrame(() => {\n\n this._loadUrdf(this.package, this.urdf);\n this._loadScheduled = false;\n\n });\n\n }\n\n // Watch the package and urdf field and load the robot model.\n // This should _only_ be called from _scheduleLoad because that\n // ensures the that current robot has been removed\n _loadUrdf(pkg, urdf) {\n\n this.dispatchEvent(new CustomEvent('urdf-change', { bubbles: true, cancelable: true, composed: true }));\n\n if (urdf) {\n\n // Keep track of this request and make\n // sure it doesn't get overwritten by\n // a subsequent one\n this._requestId++;\n const requestId = this._requestId;\n\n const updateMaterials = mesh => {\n\n mesh.traverse(c => {\n\n if (c instanceof Mesh) {\n\n // Add to shadow generator\n this._shadowGenerator.addShadowCaster(c);\n c.receiveShadows = true;\n\n }\n\n });\n\n };\n\n if (pkg.includes(':') && (pkg.split(':')[1].substring(0, 2)) !== '//') {\n\n pkg = pkg.split(',').reduce((map, value) => {\n\n const split = value.split(/:/).filter(x => !!x);\n const pkgName = split.shift().trim();\n const pkgPath = split.join(':').trim();\n map[pkgName] = pkgPath;\n\n return map;\n\n }, {});\n }\n\n let robot = null;\n const loader = new URDFLoader(this.scene);\n loader.packages = pkg;\n if (this.loadMeshFunc) {\n\n loader.loadMeshCb = this.loadMeshFunc;\n\n }\n loader.fetchOptions = { mode: 'cors', credentials: 'same-origin' };\n loader.parseCollision = true;\n\n loader.manager.onLoad = () => {\n\n // If another request has come in to load a new\n // robot, then ignore this one\n if (this._requestId !== requestId) {\n\n if (robot) robot.traverse(c => c.dispose && c.dispose());\n return;\n\n }\n\n this.robot = robot;\n robot.parent = this.world;\n updateMaterials(robot);\n\n this._setIgnoreLimits(this.ignoreLimits);\n this._updateCollisionVisibility();\n\n this.dispatchEvent(new CustomEvent('urdf-processed', { bubbles: true, cancelable: true, composed: true }));\n this.dispatchEvent(new CustomEvent('geometry-loaded', { bubbles: true, cancelable: true, composed: true }));\n\n this.recenter();\n\n };\n\n loader.load(urdf, model => robot = model);\n\n }\n\n }\n\n _updateCollisionVisibility() {\n\n const showCollision = this.showCollision;\n const collisionMaterial = this._collisionMaterial;\n const robot = this.robot;\n\n if (robot === null) return;\n\n const colliders = [];\n robot.traverse(c => {\n\n if (c.isURDFCollider) {\n\n c.setEnabled(showCollision);\n colliders.push(c);\n\n }\n\n });\n\n colliders.forEach(coll => {\n\n coll.traverse(c => {\n\n if (c instanceof Mesh) {\n\n c.isPickable = false;\n c.material = collisionMaterial;\n\n }\n\n });\n\n });\n\n }\n\n // Watch the coordinate frame and update the\n // rotation of the scene to match\n _setUp(up) {\n\n if (!up) up = '+Z';\n up = up.toUpperCase();\n const sign = up.replace(/[^-+]/g, '')[0] || '+';\n const axis = up.replace(/[^XYZ]/gi, '')[0] || 'Z';\n\n if (!this.world) return;\n\n const PI = Math.PI;\n const HALFPI = PI / 2;\n\n let rx = 0, rz = 0;\n const ry = 0;\n if (axis === 'X') { rz = sign === '+' ? HALFPI : -HALFPI; }\n if (axis === 'Z') { rx = sign === '+' ? -HALFPI : HALFPI; }\n if (axis === 'Y') { rx = sign === '+' ? 0 : PI; }\n\n this.world.rotationQuaternion = Quaternion.RotationYawPitchRoll(ry, rx, rz);\n\n }\n\n // Updates the current robot's angles to ignore\n // joint limits or not\n _setIgnoreLimits(ignore, dispatch = false) {\n\n if (this.robot) {\n\n Object\n .values(this.robot.joints)\n .forEach(joint => {\n\n joint.ignoreLimits = ignore;\n joint.setJointValue(...joint.jointValue);\n\n });\n\n }\n\n if (dispatch) {\n\n this.dispatchEvent(new CustomEvent('ignore-limits-change', { bubbles: true, cancelable: true, composed: true }));\n\n }\n\n }\n\n}\n"],"names":["Engine","Scene","Color4","HemisphericLight","Vector3","Color3","DirectionalLight","ShadowGenerator","ArcRotateCamera","TransformNode","Quaternion","MeshBuilder","StandardMaterial","Material","Mesh"],"mappings":"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"}