zincjs 1.0.13 → 1.0.15

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.
Files changed (45) hide show
  1. package/build/zinc.frontend.js +1 -1
  2. package/build/zinc.js +43 -35
  3. package/build/zinc.js.map +1 -1
  4. package/package.json +3 -3
  5. package/src/assets/disc.png +0 -0
  6. package/src/assets/mapMarker.svg +11 -0
  7. package/src/controls.js +1594 -0
  8. package/src/geometryCSG.js +148 -0
  9. package/src/glyphsetCSG.js +84 -0
  10. package/src/loaders/GLTFToZincJSLoader.js +85 -0
  11. package/src/loaders/JSONLoader.js +697 -0
  12. package/src/loaders/OBJLoader.js +911 -0
  13. package/src/loaders/STLLoader.js +399 -0
  14. package/src/loaders/primitivesLoader.js +46 -0
  15. package/src/minimap.js +82 -0
  16. package/src/primitives/augmentShader.js +22 -0
  17. package/src/primitives/geometry.js +109 -0
  18. package/src/primitives/glyph.js +150 -0
  19. package/src/primitives/glyphset.js +657 -0
  20. package/src/primitives/label.js +51 -0
  21. package/src/primitives/lines.js +35 -0
  22. package/src/primitives/marker.js +88 -0
  23. package/src/primitives/pointset.js +53 -0
  24. package/src/primitives/texturePrimitive.js +16 -0
  25. package/src/primitives/textureSlides.js +118 -0
  26. package/src/primitives/zincObject.js +573 -0
  27. package/src/region.js +554 -0
  28. package/src/renderer.js +612 -0
  29. package/src/scene.js +963 -0
  30. package/src/sceneExporter.js +32 -0
  31. package/src/sceneLoader.js +842 -0
  32. package/src/texture/texture.js +57 -0
  33. package/src/texture/textureArray.js +85 -0
  34. package/src/three/GLTFExporter.js +2448 -0
  35. package/src/three/Geometry.js +2084 -0
  36. package/src/three/Loader.js +344 -0
  37. package/src/three/Points.js +223 -0
  38. package/src/three/line/Line.js +293 -0
  39. package/src/three/line/LineSegments.js +65 -0
  40. package/src/three-js-csg.js +564 -0
  41. package/src/utilities.js +321 -0
  42. package/src/videoHandler.js +92 -0
  43. package/src/workers/geometryCSG.worker.js +73 -0
  44. package/src/workers/geometryCSGInternal.js +58 -0
  45. package/src/zinc.js +38 -0
@@ -0,0 +1,612 @@
1
+ const THREE = require('three');
2
+ const ResizeSensor = require('css-element-queries/src/ResizeSensor');
3
+ /**
4
+ * Create a Zinc 3D renderer in the container provided.
5
+ * The primary function of a Zinc 3D renderer is to display the current
6
+ * scene (@link Zinc.Scene} set to the renderer and each scene may contain as
7
+ * many geometries, glyphset and other primitives as the system can support.
8
+ * Zinc.Renderer also allows additional scenes to be displayed.
9
+ *
10
+ * @param {Object} containerIn - Container to create the renderer on.
11
+ * @class
12
+ * @author Alan Wu
13
+ * @return {Zinc.Renderer}
14
+ */
15
+ exports.Renderer = function (containerIn) {
16
+
17
+ let container = containerIn;
18
+
19
+ const stats = 0;
20
+
21
+ let renderer = undefined;
22
+ let currentScene = undefined;
23
+
24
+ //myGezincGeometriestains a tuple of the threejs mesh, timeEnabled, morphColour flag, unique id and morph
25
+ const clock = new THREE.Clock(false);
26
+ this.playAnimation = true;
27
+ /* default animation update rate, rate is 1000 and duration
28
+ is default to 6000, 6s to finish a full animation */
29
+ let playRate = 1000;
30
+ let preRenderCallbackFunctions = [];
31
+ let preRenderCallbackFunctions_id = 0;
32
+ let postRenderCallbackFunctions = [];
33
+ let postRenderCallbackFunctions_id = 0;
34
+ let animated_id = undefined;
35
+ let cameraOrtho = undefined, sceneOrtho = undefined, logoSprite = undefined;
36
+ let sceneMap = [];
37
+ let additionalActiveScenes = [];
38
+ let scenesGroup = new THREE.Group();
39
+ let canvas = undefined;
40
+ let sensor = undefined;
41
+ let isRendering = false;
42
+ const _this = this;
43
+ const currentSize = [0, 0];
44
+ const currentOffset = [0, 0];
45
+
46
+ this.getDrawingWidth = () => {
47
+ if (container) {
48
+ return container.clientWidth;
49
+ } else if (canvas)
50
+ if (typeof canvas.clientWidth !== 'undefined')
51
+ return Math.round(canvas.clientWidth);
52
+ else
53
+ return Math.round(canvas.width);
54
+ return 0;
55
+ }
56
+
57
+ this.getDrawingHeight = () => {
58
+ if (container) {
59
+ return container.clientHeight;
60
+ } else if (canvas)
61
+ if (typeof canvas.clientHeight !== 'undefined')
62
+ return Math.round(canvas.clientHeight);
63
+ else
64
+ return Math.round(canvas.height);
65
+ return 0;
66
+ }
67
+
68
+ /**
69
+ * Call this to resize the renderer, this is normally call automatically.
70
+ */
71
+ this.onWindowResize = () => {
72
+ currentScene.onWindowResize();
73
+ const width = this.getDrawingWidth();
74
+ const height = this.getDrawingHeight();
75
+ if (renderer != undefined) {
76
+ let rect = undefined;
77
+ if (container) {
78
+ rect = container.getBoundingClientRect();
79
+ renderer.setSize(width, height);
80
+ } else if (canvas) {
81
+ if (typeof canvas.getBoundingClientRect !== 'undefined') {
82
+ rect = canvas.getBoundingClientRect();
83
+ canvas.width = width;
84
+ canvas.height = height;
85
+ renderer.setSize(width, height, false);
86
+ } else {
87
+ renderer.setSize(width, height, false);
88
+
89
+ }
90
+ }
91
+ if (rect) {
92
+ currentOffset[0] = rect.left;
93
+ currentOffset[1] = rect.top;
94
+ }
95
+ const target = new THREE.Vector2();
96
+ renderer.getSize(target);
97
+ currentSize[0] = target.x;
98
+ currentSize[1] = target.y;
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Initialise the renderer and its visualisations.
104
+ */
105
+ this.initialiseVisualisation = parameters => {
106
+ parameters = parameters || {};
107
+ if (parameters['antialias'] === undefined) {
108
+ let onMobile = false;
109
+ try {
110
+ if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
111
+ onMobile = true;
112
+ }
113
+ }
114
+ catch(err) {
115
+ onMobile = false;
116
+ }
117
+ if (onMobile)
118
+ parameters['antialias'] = false;
119
+ else
120
+ parameters['antialias'] = true;
121
+ }
122
+ if (parameters["canvas"]) {
123
+ container = undefined;
124
+ canvas = parameters["canvas"];
125
+ }
126
+ renderer = new THREE.WebGLRenderer(parameters);
127
+ if (container !== undefined) {
128
+ container.appendChild( renderer.domElement );
129
+ }
130
+ renderer.setClearColor( 0xffffff, 1);
131
+ if (canvas && canvas.style) {
132
+ canvas.style.height = "100%";
133
+ canvas.style.width = "100%";
134
+ }
135
+ renderer.autoClear = false;
136
+ const scene = this.createScene("default");
137
+ this.setCurrentScene(scene);
138
+ }
139
+
140
+ /**
141
+ * Get the current scene on display.
142
+ * @return {Zinc.Scene};
143
+ */
144
+ this.getCurrentScene = () => {
145
+ return currentScene;
146
+ }
147
+
148
+ /**
149
+ * Set the current scene on display.
150
+ *
151
+ * @param {Zinc.Scene} sceneIn - The scene to be set, only scene created by this instance
152
+ * of ZincRenderer is supported currently.
153
+ */
154
+ this.setCurrentScene = sceneIn => {
155
+ if (sceneIn) {
156
+ this.removeActiveScene(sceneIn);
157
+ const oldScene = currentScene;
158
+ currentScene = sceneIn;
159
+ if (oldScene) {
160
+ oldScene.setInteractiveControlEnable(false);
161
+ }
162
+ currentScene.setInteractiveControlEnable(true);
163
+ currentScene.setAdditionalScenesGroup(scenesGroup);
164
+ this.onWindowResize();
165
+ }
166
+ }
167
+
168
+ /**
169
+ * Return scene with the matching name if scene with that name has been created.
170
+ *
171
+ * @param {String} name - Name to match
172
+ * @return {Zinc.Scene}
173
+ */
174
+ this.getSceneByName = name => {
175
+ return sceneMap[name];
176
+ }
177
+
178
+ /**
179
+ * Create a new scene with the provided name if scene with the same name exists,
180
+ * return undefined.
181
+ *
182
+ * @param {String} name - Name of the scene to be created.
183
+ * @return {Zinc.Scene}
184
+ */
185
+ this.createScene = name => {
186
+ if (sceneMap[name] != undefined){
187
+ return undefined;
188
+ } else {
189
+ let new_scene = undefined;
190
+ if (canvas)
191
+ new_scene = new (require('./scene').Scene)(canvas, renderer);
192
+ else
193
+ new_scene = new (require('./scene').Scene)(container, renderer);
194
+ sceneMap[name] = new_scene;
195
+ new_scene.sceneName = name;
196
+ return new_scene;
197
+ }
198
+ }
199
+
200
+ const updateOrthoScene = () => {
201
+ if (logoSprite != undefined) {
202
+ const material = logoSprite.material;
203
+ if (material.map) {
204
+ const width = this.getDrawingWidth();
205
+ const height = this.getDrawingHeight();
206
+ const calculatedWidth = (width - material.map.image.width)/2;
207
+ const calculatedHeight = (-height + material.map.image.height)/2;
208
+ logoSprite.position.set(calculatedWidth, calculatedHeight, 1 );
209
+ }
210
+ }
211
+ };
212
+
213
+ const updateOrthoCamera = () => {
214
+ if (cameraOrtho != undefined) {
215
+ const width = this.getDrawingWidth();
216
+ const height = this.getDrawingHeight();
217
+ cameraOrtho.left = -width / 2;
218
+ cameraOrtho.right = width / 2;
219
+ cameraOrtho.top = height / 2;
220
+ cameraOrtho.bottom = -height / 2;
221
+ cameraOrtho.updateProjectionMatrix();
222
+ }
223
+ };
224
+
225
+ /**
226
+ * Reset the viewport of the current scene to its original state.
227
+ */
228
+ this.resetView = () => {
229
+ currentScene.resetView();
230
+ }
231
+
232
+ /**
233
+ * Adjust zoom distance to include all primitives in scene and also the additional scenes
234
+ * but the lookat direction and up vectors will remain constant.
235
+ */
236
+ this.viewAll = () => {
237
+ if (currentScene) {
238
+ const boundingBox = currentScene.getBoundingBox();
239
+ if (boundingBox) {
240
+ for(i = 0; i < additionalActiveScenes.length; i++) {
241
+ const boundingBox2 = additionalActiveScenes[i].getBoundingBox();
242
+ if (boundingBox2) {
243
+ boundingBox.union(boundingBox2);
244
+ }
245
+ }
246
+ currentScene.viewAllWithBoundingBox(boundingBox);
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Load a legacy model(s) format with the provided URLs and parameters. This only loads the geometry
253
+ * without any of the metadata. Therefore, extra parameters should be provided. This should be
254
+ * called from {@link Zinc.Scene}.
255
+ *
256
+ * @deprecated
257
+ */
258
+ this.loadModelsURL = (urls, colours, opacities, timeEnabled, morphColour, finishCallback) => {
259
+ currentScene.loadModelsURL(urls, colours, opacities, timeEnabled, morphColour, finishCallback);
260
+ }
261
+
262
+ const loadView = viewData => {
263
+ currentScene.loadView(viewData);
264
+ };
265
+
266
+ /**
267
+ * Load the viewport from an external location provided by the url. This should be
268
+ * called from {@link Zinc.Scene};
269
+ * @param {String} URL - address to the file containing viewport information.
270
+ * @deprecated
271
+ */
272
+ this.loadViewURL = url => {
273
+ currentScene.loadViewURL(url);
274
+ }
275
+
276
+ /**
277
+ * Load a legacy file format containing the viewport and its model file from an external
278
+ * location provided by the url. Use the new metadata format with
279
+ * {@link Zinc.Scene#loadMetadataURL} instead. This should be
280
+ * called from {@link Zinc.Scene};
281
+ *
282
+ * @param {String} URL - address to the file containing viewport and model information.
283
+ * @deprecated
284
+ */
285
+ this.loadFromViewURL = (jsonFilePrefix, finishCallback) => {
286
+ currentScene.loadFromViewURL(jsonFilePrefix, finishCallback);
287
+ }
288
+
289
+ this.updateDirectionalLight = () => {
290
+ currentScene.updateDirectionalLight();
291
+ }
292
+
293
+ let runAnimation = () => {
294
+ if (isRendering) {
295
+ animated_id = requestAnimationFrame( runAnimation );
296
+ this.render();
297
+ } else {
298
+ cancelAnimationFrame(animated_id);
299
+ animated_id = undefined;
300
+ }
301
+ }
302
+
303
+ /**
304
+ * Stop the animation and renderer to get into the render loop.
305
+ */
306
+ this.stopAnimate = () => {
307
+ if (isRendering) {
308
+ clock.stop();
309
+ isRendering = false;
310
+ }
311
+ }
312
+
313
+ /**
314
+ * Start the animation and begin the rendering loop.
315
+ */
316
+ this.animate = () => {
317
+ if (!isRendering) {
318
+ clock.start();
319
+ isRendering = true;
320
+ runAnimation();
321
+ }
322
+ }
323
+
324
+ const prevTime = Date.now();
325
+
326
+ /**
327
+ * Add a callback function which will be called everytime before the renderer renders its scene.
328
+ * @param {Function} callbackFunction - callbackFunction to be added.
329
+ *
330
+ * @return {Number}
331
+ */
332
+ this.addPreRenderCallbackFunction = callbackFunction => {
333
+ preRenderCallbackFunctions_id = preRenderCallbackFunctions_id + 1;
334
+ preRenderCallbackFunctions[preRenderCallbackFunctions_id] = callbackFunction;
335
+ return preRenderCallbackFunctions_id;
336
+ }
337
+
338
+ /**
339
+ * Remove a callback function that is previously added to the scene.
340
+ * @param {Number} id - identifier of the previously added callback function.
341
+ */
342
+ this.removePreRenderCallbackFunction = id => {
343
+ if (id in preRenderCallbackFunctions) {
344
+ delete preRenderCallbackFunctions[id];
345
+ }
346
+ }
347
+
348
+ /**
349
+ * Add a callback function which will be called everytime after the renderer renders its scene.
350
+ * @param {Function} callbackFunction - callbackFunction to be added.
351
+ *
352
+ * @return {Number}
353
+ */
354
+ this.addPostRenderCallbackFunction = callbackFunction => {
355
+ postRenderCallbackFunctions_id = postRenderCallbackFunctions_id + 1;
356
+ postRenderCallbackFunctions[postRenderCallbackFunctions_id] = callbackFunction;
357
+ return postRenderCallbackFunctions_id;
358
+ }
359
+
360
+ /**
361
+ * Remove a callback function that is previously added to the scene.
362
+ * @param {Number} id - identifier of the previously added callback function.
363
+ */
364
+ this.removePostRenderCallbackFunction = id => {
365
+ if (id in postRenderCallbackFunctions) {
366
+ delete postRenderCallbackFunctions[id];
367
+ }
368
+ }
369
+
370
+ /**
371
+ * Get the current play rate, playrate affects how fast an animated object animates.
372
+ * Also see {@link Zinc.Scene#duration}.
373
+ */
374
+ this.getPlayRate = () => {
375
+ return playRate;
376
+ }
377
+
378
+ /**
379
+ * Set the current play rate, playrate affects how fast an animated object animates.
380
+ * @param {Number} PlayRateIn - value to set the playrate to.
381
+ * Also see {@link Zinc.Scene#duration}.
382
+ */
383
+ this.setPlayRate = playRateIn => {
384
+ playRate = playRateIn;
385
+ }
386
+
387
+ this.getCurrentTime = () => {
388
+ return currentScene.getCurrentTime();
389
+ }
390
+
391
+
392
+ /**
393
+ * Get the current play rate, playrate affects how fast an animated object animates.
394
+ * Also see {@link Zinc.Scene#duration}.
395
+ */
396
+ this.setMorphsTime = time => {
397
+ currentScene.setMorphsTime(time);
398
+ }
399
+
400
+ /**
401
+ * Get {Zinc.Geoemtry} by its id. This should be called from {@link Zinc.Scene};
402
+ *
403
+ * @depreacted
404
+ * @return {Zinc.Geometry}
405
+ */
406
+ this.getZincGeometryByID = id => {
407
+ return currentScene.getZincGeometryByID(id);
408
+ }
409
+
410
+ /**
411
+ * Add {Three.Object} to the current scene.
412
+ */
413
+ this.addToScene = object => {
414
+ currentScene.addObject(object)
415
+ }
416
+
417
+ /**
418
+ * Add {Three.Object} to the ortho scene, objects added to the ortho scene are rendered in
419
+ * normalised coordinates and overlay on top of current scene.
420
+ *
421
+ */
422
+ this.addToOrthoScene = object => {
423
+ if (sceneOrtho == undefined)
424
+ sceneOrtho = new THREE.Scene();
425
+ if (cameraOrtho == undefined) {
426
+ const width = this.getDrawingWidth();
427
+ const height = this.getDrawingHeight();
428
+ cameraOrtho = new THREE.OrthographicCamera( -width / 2,
429
+ width / 2, height/ 2, -height / 2, 1, 10 );
430
+ cameraOrtho.position.z = 10;
431
+ }
432
+ sceneOrtho.add(object)
433
+ }
434
+
435
+ const createHUDSprites = logoSprite => {
436
+ return texture => {
437
+ texture.needsUpdate = true;
438
+ const material = new THREE.SpriteMaterial( { map: texture } );
439
+ const imagewidth = material.map.image.width;
440
+ const imageheight = material.map.image.height;
441
+ logoSprite.material = material;
442
+ logoSprite.scale.set( imagewidth, imageheight, 1 );
443
+ const width = this.getDrawingWidth();
444
+ const height = this.getDrawingHeight();
445
+ logoSprite.position.set( (width - imagewidth)/2, (-height + imageheight)/2, 1 );
446
+ this.addToOrthoScene(logoSprite);
447
+ };
448
+ };
449
+
450
+ this.addLogo = () => {
451
+ logoSprite = new THREE.Sprite();
452
+ const logo = THREE.ImageUtils.loadTexture(
453
+ "images/abi_big_logo_transparent_small.png", undefined, createHUDSprites(logoSprite));
454
+ }
455
+
456
+ /**
457
+ * Render the current and all additional scenes. It will first update all geometries and glyphsets
458
+ * in scenes, clear depth buffer and render the ortho scene, call the preRenderCallbackFunctions stack
459
+ * , render the scenes then postRenderCallback.
460
+ */
461
+ this.render = () => {
462
+ if (!sensor) {
463
+ if (container) {
464
+ if (container.clientWidth > 0 && container.clientHeight > 0)
465
+ sensor = new ResizeSensor(container, this.onWindowResize);
466
+ } else if (canvas) {
467
+ if (canvas.width > 0 && canvas.height > 0)
468
+ sensor = new ResizeSensor(canvas, this.onWindowResize);
469
+ }
470
+ }
471
+ const delta = clock.getDelta();
472
+ currentScene.renderGeometries(playRate, delta, this.playAnimation);
473
+ for(i = 0; i < additionalActiveScenes.length; i++) {
474
+ const sceneItem = additionalActiveScenes[i];
475
+ sceneItem.renderGeometries(playRate, delta, this.playAnimation);
476
+ }
477
+ if (cameraOrtho != undefined && sceneOrtho != undefined) {
478
+ renderer.clearDepth();
479
+ renderer.render( sceneOrtho, cameraOrtho );
480
+ }
481
+ for (key in preRenderCallbackFunctions) {
482
+ if (preRenderCallbackFunctions.hasOwnProperty(key)) {
483
+ preRenderCallbackFunctions[key].call();
484
+ }
485
+ }
486
+ currentScene.render(renderer);
487
+ for (key in postRenderCallbackFunctions) {
488
+ if (postRenderCallbackFunctions.hasOwnProperty(key)) {
489
+ postRenderCallbackFunctions[key].call();
490
+ }
491
+ }
492
+ }
493
+
494
+ /**
495
+ * Get the internal {@link Three.Renderer}, to gain access to ThreeJS APIs.
496
+ */
497
+ this.getThreeJSRenderer = () => {
498
+ return renderer;
499
+ }
500
+
501
+ /**
502
+ * Check if a scene is currently active.
503
+ * @param {Zinc.Scene} sceneIn - Scene to check if it is currently
504
+ * rendered.
505
+ */
506
+ this.isSceneActive = sceneIn => {
507
+ if (currentScene === sceneIn) {
508
+ return true;
509
+ } else {
510
+ for(i = 0; i < additionalActiveScenes.length; i++) {
511
+ const sceneItem = additionalActiveScenes[i];
512
+ if (sceneItem === sceneIn)
513
+ return true;
514
+ }
515
+ }
516
+ return false;
517
+ }
518
+
519
+ /**
520
+ * Add additional active scene for rendering, this scene will also be rendered but
521
+ * viewport of the currentScene will be used.
522
+ * @param {Zinc.Scene} additionalScene - Scene to be added to the rendering.
523
+ */
524
+ this.addActiveScene = additionalScene => {
525
+ if (!this.isSceneActive(additionalScene)) {
526
+ additionalActiveScenes.push(additionalScene);
527
+ scenesGroup.add(additionalScene.getThreeJSScene());
528
+ }
529
+ }
530
+
531
+ /**
532
+ * Remove a currenrtly active scene from the renderer, this scene will also be rendered but
533
+ * viewport of the currentScene will be used.
534
+ * @param {Zinc.Scene} additionalScene - Scene to be removed from rendering.
535
+ */
536
+ this.removeActiveScene = additionalScene => {
537
+ for(i = 0; i < additionalActiveScenes.length; i++) {
538
+ const sceneItem = additionalActiveScenes[i];
539
+ if (sceneItem === additionalScene) {
540
+ additionalActiveScenes.splice(i, 1);
541
+ scenesGroup.remove(additionalScene.getThreeJSScene());
542
+ return;
543
+ }
544
+ }
545
+ }
546
+
547
+ /**
548
+ * Clear all additional scenes from rendering except for curentScene.
549
+ */
550
+ this.clearAllActiveScene = () => {
551
+ for (let i = 0; i < additionalActiveScenes.length; i++) {
552
+ scenesGroup.remove(additionalActiveScenes[i].getThreeJSScene());
553
+ }
554
+ additionalActiveScenes.splice(0,additionalActiveScenes.length);
555
+ }
556
+
557
+ /**
558
+ * Dispose all memory allocated, this will effetively destroy all scenes.
559
+ */
560
+ this.dispose = () => {
561
+ if (isRendering)
562
+ cancelAnimationFrame(animated_id);
563
+ for (const key in sceneMap) {
564
+ if (sceneMap.hasOwnProperty(key)) {
565
+ sceneMap[key].clearAll();
566
+ }
567
+ }
568
+ sceneMap = [];
569
+ additionalActiveScenes = [];
570
+ scenesGroup = new THREE.Group();
571
+ this.stopAnimate();
572
+ preRenderCallbackFunctions = [];
573
+ preRenderCallbackFunctions_id = 0;
574
+ cameraOrtho = undefined;
575
+ sceneOrtho = undefined;
576
+ logoSprite = undefined;
577
+ const scene = this.createScene("default");
578
+ this.setCurrentScene(scene);
579
+ sensor = undefined;
580
+ }
581
+
582
+ /**
583
+ * Transition from the current viewport to the endingScene's viewport in the specified duration.
584
+ *
585
+ * @param {Zinc.Scene} endingScene - Viewport of this scene will be used as the destination.
586
+ * @param {Number} duration - Amount of time to transition from current viewport to the
587
+ * endingScene's viewport.
588
+ */
589
+ this.transitionScene = (endingScene, duration) => {
590
+ if (currentScene) {
591
+ const currentCamera = currentScene.getZincCameraControls();
592
+ const boundingBox = endingScene.getBoundingBox();
593
+ if (boundingBox) {
594
+ const radius = boundingBox.min.distanceTo(boundingBox.max)/2.0;
595
+ const centreX = (boundingBox.min.x + boundingBox.max.x) / 2.0;
596
+ const centreY = (boundingBox.min.y + boundingBox.max.y) / 2.0;
597
+ const centreZ = (boundingBox.min.z + boundingBox.max.z) / 2.0;
598
+ const clip_factor = 4.0;
599
+ const endingViewport = currentCamera.getViewportFromCentreAndRadius(centreX, centreY, centreZ, radius, 40, radius * clip_factor );
600
+ const startingViewport = currentCamera.getCurrentViewport();
601
+ currentCamera.cameraTransition(startingViewport, endingViewport, duration);
602
+ currentCamera.enableCameraTransition();
603
+ }
604
+ }
605
+ }
606
+
607
+ this.isWebGL2 = () => {
608
+ if (renderer)
609
+ return renderer.capabilities.isWebGL2;
610
+ return false;
611
+ }
612
+ };