zincjs 3.0.0 → 3.0.1

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 (60) hide show
  1. package/README.md +27 -22
  2. package/build/zinc.js +2 -2
  3. package/build/zinc.js.map +1 -1
  4. package/package.json +4 -1
  5. package/src/controls.js +1332 -1241
  6. package/src/geometryCSG.js +111 -115
  7. package/src/glyphsetCSG.js +51 -55
  8. package/src/loaders/GLTFToZincJSLoader.js +31 -33
  9. package/src/loaders/JSONLoader.js +339 -449
  10. package/src/loaders/OBJLoader.js +654 -851
  11. package/src/loaders/STLLoader.js +271 -329
  12. package/src/loaders/niftiReader.js +90 -59
  13. package/src/loaders/primitivesLoader.js +55 -52
  14. package/src/minimap.js +63 -43
  15. package/src/primitives/geometry.js +40 -44
  16. package/src/primitives/glyph.js +16 -19
  17. package/src/primitives/glyphset.js +229 -185
  18. package/src/primitives/label.js +29 -31
  19. package/src/primitives/lines.js +20 -20
  20. package/src/primitives/lines2.js +33 -39
  21. package/src/primitives/lod.js +43 -43
  22. package/src/primitives/marker.js +31 -32
  23. package/src/primitives/markerCluster.js +32 -35
  24. package/src/primitives/pointset.js +86 -83
  25. package/src/primitives/texturePrimitive.js +9 -10
  26. package/src/primitives/textureSlides.js +84 -97
  27. package/src/primitives/textureVolume.js +46 -49
  28. package/src/primitives/tubeLines.js +108 -108
  29. package/src/primitives/zincObject.js +176 -184
  30. package/src/region.js +145 -155
  31. package/src/renderRequests.js +3 -3
  32. package/src/renderer.js +635 -620
  33. package/src/scene.js +479 -419
  34. package/src/sceneExporter.js +22 -17
  35. package/src/sceneLoader.js +542 -296
  36. package/src/shaders/rgbVolumeRender.js +11 -18
  37. package/src/shaders/textureArray.js +5 -12
  38. package/src/shaders/textureSlide.js +10 -17
  39. package/src/shaders/volumeRender.js +11 -18
  40. package/src/shaders/volumeRender_old.js +11 -18
  41. package/src/shaders/volumeTexture.js +7 -14
  42. package/src/textSprite.js +23 -19
  43. package/src/texture/texture.js +14 -15
  44. package/src/texture/textureArray.js +14 -16
  45. package/src/three/InstancedPoints.js +2 -9
  46. package/src/three/Loader.js +334 -315
  47. package/src/three/line/Line.js +165 -215
  48. package/src/three/line/LineSegments.js +40 -55
  49. package/src/three/line/LineSegments2.js +322 -366
  50. package/src/three/line/LineSegmentsGeometry.js +239 -280
  51. package/src/three-js-csg.js +260 -252
  52. package/src/tsl/glyphRenderMaterial.js +12 -3
  53. package/src/tsl/glyphTransform.js +51 -29
  54. package/src/tsl/textureSlides.js +23 -24
  55. package/src/utilities.js +309 -371
  56. package/src/videoHandler.js +76 -83
  57. package/src/workers/geometryCSG.worker.js +33 -36
  58. package/src/workers/geometryCSGInternal.js +39 -44
  59. package/src/zinc.js +4 -7
  60. package/vite.config.js +7 -7
package/src/renderer.js CHANGED
@@ -17,139 +17,137 @@ import { setGlyphComputeSupported } from './tsl/glyphTransform';
17
17
  * @return {Renderer}
18
18
  */
19
19
  const Renderer = function (containerIn) {
20
+ let container = containerIn;
20
21
 
21
- let container = containerIn;
22
+ const stats = 0;
22
23
 
23
- const stats = 0;
24
+ let renderer = undefined;
25
+ let currentScene = undefined;
24
26
 
25
- let renderer = undefined;
26
- let currentScene = undefined;
27
-
28
- //myGezincGeometriestains a tuple of the threejs mesh, timeEnabled, morphColour flag, unique id and morph
29
- const clock = new THREE.Timer();
30
- this.playAnimation = true;
27
+ //myGezincGeometriestains a tuple of the threejs mesh, timeEnabled, morphColour flag, unique id and morph
28
+ const clock = new THREE.Timer();
29
+ this.playAnimation = true;
31
30
  /* default animation update rate, rate is 1000 and duration
32
31
  is default to 6000, 6s to finish a full animation */
33
- let playRate = 1000;
34
- let preRenderCallbackFunctions = {};
35
- let preRenderCallbackFunctions_id = 0;
36
- let postRenderCallbackFunctions = {};
37
- let postRenderCallbackFunctions_id = 0;
38
- let contextLostCallbackFunctions = {};
39
- let contextLostCallbackFunctions_id = 0;
40
- let contextRestoredCallbackFunctions = {};
41
- let contextRestoredCallbackFunctions_id = 0;
42
- let animated_id = undefined;
43
- let cameraOrtho = undefined, sceneOrtho = undefined, logoSprite = undefined;
44
- let sceneMap = [];
45
- let additionalActiveScenes = [];
46
- let scenesGroup = new THREE.Group();
47
- let canvas = undefined;
32
+ let playRate = 1000;
33
+ let preRenderCallbackFunctions = {};
34
+ let preRenderCallbackFunctions_id = 0;
35
+ let postRenderCallbackFunctions = {};
36
+ let postRenderCallbackFunctions_id = 0;
37
+ let contextLostCallbackFunctions = {};
38
+ let contextLostCallbackFunctions_id = 0;
39
+ let contextRestoredCallbackFunctions = {};
40
+ let contextRestoredCallbackFunctions_id = 0;
41
+ let animated_id = undefined;
42
+ let cameraOrtho = undefined,
43
+ sceneOrtho = undefined,
44
+ logoSprite = undefined;
45
+ let sceneMap = [];
46
+ let additionalActiveScenes = [];
47
+ let scenesGroup = new THREE.Group();
48
+ let canvas = undefined;
48
49
  let sensor = undefined;
49
50
  let isRendering = false;
50
- let isInitialised = false;
51
- const _this = this;
52
- const currentSize = [0, 0];
53
- const currentOffset = [0, 0];
54
- //Render on demand is opt-in, when enabled the scene is only drawn when
55
- //something has changed.
56
- let renderOnDemand = false;
57
- let needsRender = true;
58
- const requestRender = () => {
59
- needsRender = true;
60
- }
61
- //Camera of the current scene shared with additional active scenes
62
- const sharedCamera = { controls: undefined, updated: false };
63
-
64
- this.getDrawingWidth = () => {
65
- if (container) {
66
- return container.clientWidth;
67
- } else if (canvas)
68
- if (typeof canvas.clientWidth !== 'undefined')
69
- return Math.round(canvas.clientWidth);
70
- else
71
- return Math.round(canvas.width);
72
- return 0;
73
- }
74
-
75
- this.getDrawingHeight = () => {
76
- if (container) {
77
- return container.clientHeight;
78
- } else if (canvas)
79
- if (typeof canvas.clientHeight !== 'undefined')
80
- return Math.round(canvas.clientHeight);
81
- else
82
- return Math.round(canvas.height);
83
- return 0;
84
- }
51
+ let isInitialised = false;
52
+ const _this = this;
53
+ const currentSize = [0, 0];
54
+ const currentOffset = [0, 0];
55
+ //Render on demand is opt-in, when enabled the scene is only drawn when
56
+ //something has changed.
57
+ let renderOnDemand = false;
58
+ let needsRender = true;
59
+ const requestRender = () => {
60
+ needsRender = true;
61
+ };
62
+ //Camera of the current scene shared with additional active scenes
63
+ const sharedCamera = { controls: undefined, updated: false };
64
+
65
+ this.getDrawingWidth = () => {
66
+ if (container) {
67
+ return container.clientWidth;
68
+ } else if (canvas)
69
+ if (typeof canvas.clientWidth !== 'undefined') return Math.round(canvas.clientWidth);
70
+ else return Math.round(canvas.width);
71
+ return 0;
72
+ };
73
+
74
+ this.getDrawingHeight = () => {
75
+ if (container) {
76
+ return container.clientHeight;
77
+ } else if (canvas)
78
+ if (typeof canvas.clientHeight !== 'undefined') return Math.round(canvas.clientHeight);
79
+ else return Math.round(canvas.height);
80
+ return 0;
81
+ };
85
82
 
86
- /**
87
- * Call this to resize the renderer, this is normally call automatically.
88
- */
89
- this.onWindowResize = () => {
90
- needsRender = true;
91
- currentScene.onWindowResize();
92
- //Give it a miniumum size of 1 x 1
93
- const width = this.getDrawingWidth() || 1;
94
- const height = this.getDrawingHeight() || 1;
95
- if (renderer != undefined) {
96
- let localRect = undefined;
97
- if (container) {
98
- localRect = container.getBoundingClientRect();
99
- renderer.setSize(width, height);
100
- } else if (canvas) {
101
- if (typeof canvas.getBoundingClientRect !== 'undefined') {
102
- localRect = canvas.getBoundingClientRect();
103
- canvas.width = width;
104
- canvas.height = height;
105
- renderer.setSize(width, height, false);
106
- } else {
107
- renderer.setSize(width, height, false);
108
-
109
- }
110
- }
111
- if (localRect) {
112
- currentOffset[0] = localRect.left;
113
- currentOffset[1] = localRect.top;
114
- }
115
- const target = new THREE.Vector2();
116
- renderer.getSize(target);
117
- currentSize[0] = target.x;
118
- currentSize[1] = target.y;
119
- //Text sprites are drawn at the resolution they occupy on screen
120
- const fov = currentScene?.camera?.fov;
121
- if (fov) {
122
- setTextPixelsPerUnit(currentSize[1] * renderer.getPixelRatio() /
123
- (2 * Math.tan(fov * Math.PI / 360)));
124
- }
125
- }
126
- }
83
+ /**
84
+ * Call this to resize the renderer, this is normally call automatically.
85
+ */
86
+ this.onWindowResize = () => {
87
+ needsRender = true;
88
+ currentScene.onWindowResize();
89
+ //Give it a miniumum size of 1 x 1
90
+ const width = this.getDrawingWidth() || 1;
91
+ const height = this.getDrawingHeight() || 1;
92
+ if (renderer != undefined) {
93
+ let localRect = undefined;
94
+ if (container) {
95
+ localRect = container.getBoundingClientRect();
96
+ renderer.setSize(width, height);
97
+ } else if (canvas) {
98
+ if (typeof canvas.getBoundingClientRect !== 'undefined') {
99
+ localRect = canvas.getBoundingClientRect();
100
+ canvas.width = width;
101
+ canvas.height = height;
102
+ renderer.setSize(width, height, false);
103
+ } else {
104
+ renderer.setSize(width, height, false);
105
+ }
106
+ }
107
+ if (localRect) {
108
+ currentOffset[0] = localRect.left;
109
+ currentOffset[1] = localRect.top;
110
+ }
111
+ const target = new THREE.Vector2();
112
+ renderer.getSize(target);
113
+ currentSize[0] = target.x;
114
+ currentSize[1] = target.y;
115
+ //Text sprites are drawn at the resolution they occupy on screen
116
+ const fov = currentScene?.camera?.fov;
117
+ if (fov) {
118
+ setTextPixelsPerUnit(
119
+ (currentSize[1] * renderer.getPixelRatio()) / (2 * Math.tan((fov * Math.PI) / 360)),
120
+ );
121
+ }
122
+ }
123
+ };
127
124
 
128
- /**
129
- * Initialise the renderer and its visualisations.
130
- */
131
- this.initialiseVisualisation = async (parameters) => {
132
- if (!isInitialised) {
133
- parameters = parameters || {};
134
- if (parameters['antialias'] === undefined) {
135
- let onMobile = false;
136
- try {
137
- if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
138
- onMobile = true;
139
- }
140
- }
141
- catch(err) {
142
- onMobile = false;
143
- }
144
- if (onMobile)
145
- parameters['antialias'] = false;
146
- else
147
- parameters['antialias'] = true;
148
- }
149
- if (parameters["canvas"]) {
150
- container = undefined;
151
- canvas = parameters["canvas"];
152
- }
125
+ /**
126
+ * Initialise the renderer and its visualisations.
127
+ */
128
+ this.initialiseVisualisation = async (parameters) => {
129
+ if (!isInitialised) {
130
+ parameters = parameters || {};
131
+ if (parameters['antialias'] === undefined) {
132
+ let onMobile = false;
133
+ try {
134
+ if (
135
+ /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
136
+ navigator.userAgent,
137
+ )
138
+ ) {
139
+ onMobile = true;
140
+ }
141
+ } catch (err) {
142
+ onMobile = false;
143
+ }
144
+ if (onMobile) parameters['antialias'] = false;
145
+ else parameters['antialias'] = true;
146
+ }
147
+ if (parameters['canvas']) {
148
+ container = undefined;
149
+ canvas = parameters['canvas'];
150
+ }
153
151
  //WebGPURenderer otherwise requests a device with the default
154
152
  //maxTextureArrayLayers (256 on many adapters), which is too low for
155
153
  //some currnetly sypported scaffold, and the default
@@ -157,13 +155,20 @@ const Renderer = function (containerIn) {
157
155
  //transform compute pass only needs two storage buffers, the higher
158
156
  //limit is kept as headroom. We will request the highest possible on
159
157
  //the device for both.
160
- if (parameters.device === undefined && parameters.requiredLimits === undefined &&
161
- typeof navigator !== 'undefined' && navigator.gpu) {
158
+ if (
159
+ parameters.device === undefined &&
160
+ parameters.requiredLimits === undefined &&
161
+ typeof navigator !== 'undefined' &&
162
+ navigator.gpu
163
+ ) {
162
164
  try {
163
- const adapter = await navigator.gpu.requestAdapter({ powerPreference: parameters.powerPreference });
165
+ const adapter = await navigator.gpu.requestAdapter({
166
+ powerPreference: parameters.powerPreference,
167
+ });
164
168
  if (adapter) {
165
169
  parameters.requiredLimits = {
166
170
  maxTextureArrayLayers: adapter.limits.maxTextureArrayLayers,
171
+ maxTextureDimension2D: adapter.limits.maxTextureDimension2D,
167
172
  maxStorageBuffersPerShaderStage: adapter.limits.maxStorageBuffersPerShaderStage,
168
173
  };
169
174
  }
@@ -172,127 +177,125 @@ const Renderer = function (containerIn) {
172
177
  //use its defaults.
173
178
  }
174
179
  }
175
- renderer = new THREE.WebGPURenderer(parameters);
180
+ renderer = new THREE.WebGPURenderer(parameters);
176
181
  await renderer.init();
177
182
  //GPU glyph animation requires the WebGPU backend, the WebGL fallback
178
183
  //cannot index storage buffers freely.
179
184
  setGlyphComputeSupported(renderer.backend?.isWebGPUBackend === true);
180
185
 
181
186
  //renderer = new THREE.WebGLRenderer(parameters);
182
- if (container !== undefined) {
183
- container.appendChild( renderer.domElement );
184
- }
185
- renderer.setClearColor( 0xffffff, 1);
186
- if (canvas && canvas.style) {
187
- canvas.style.height = "100%";
188
- canvas.style.width = "100%";
189
- }
190
- const domCanvas = renderer.domElement;
191
- domCanvas.addEventListener("webglcontextlost", onContextLost, false);
192
- domCanvas.addEventListener("webglcontextrestored", onContextRestored, false);
193
-
194
- renderer.autoClear = false;
195
- const scene = this.createScene("default");
196
- this.setCurrentScene(scene);
197
- onRenderRequest(requestRender);
198
- isInitialised = true;
199
- }
200
- }
187
+ if (container !== undefined) {
188
+ container.appendChild(renderer.domElement);
189
+ }
190
+ renderer.setClearColor(0xffffff, 1);
191
+ if (canvas && canvas.style) {
192
+ canvas.style.height = '100%';
193
+ canvas.style.width = '100%';
194
+ }
195
+ const domCanvas = renderer.domElement;
196
+ domCanvas.addEventListener('webglcontextlost', onContextLost, false);
197
+ domCanvas.addEventListener('webglcontextrestored', onContextRestored, false);
198
+
199
+ renderer.autoClear = false;
200
+ const scene = this.createScene('default');
201
+ this.setCurrentScene(scene);
202
+ onRenderRequest(requestRender);
203
+ isInitialised = true;
204
+ }
205
+ };
201
206
 
202
- const onContextLost = event => {
207
+ const onContextLost = (event) => {
203
208
  event.preventDefault();
204
209
  for (let key of Object.keys(preRenderCallbackFunctions)) {
205
210
  if (contextLostCallbackFunctions.hasOwnProperty(key)) {
206
211
  contextLostCallbackFunctions[key].call();
207
212
  }
208
213
  }
209
- }
214
+ };
210
215
 
211
- const onContextRestored = event => {
216
+ const onContextRestored = (event) => {
212
217
  event.preventDefault();
213
218
  for (let key of Object.keys(preRenderCallbackFunctions)) {
214
219
  if (contextRestoredCallbackFunctions.hasOwnProperty(key)) {
215
220
  contextRestoredCallbackFunctions[key].call();
216
221
  }
217
222
  }
218
- }
223
+ };
219
224
 
220
- /**
221
- * Get the current scene on display.
222
- * @return {Zinc.Scene};
223
- */
224
- this.getCurrentScene = () => {
225
- return currentScene;
226
- }
225
+ /**
226
+ * Get the current scene on display.
227
+ * @return {Zinc.Scene};
228
+ */
229
+ this.getCurrentScene = () => {
230
+ return currentScene;
231
+ };
227
232
 
228
- /**
229
- * Set the current scene on display.
230
- *
231
- * @param {Zinc.Scene} sceneIn - The scene to be set, only scene created by this instance
232
- * of ZincRenderer is supported currently.
233
- */
234
- this.setCurrentScene = sceneIn => {
235
- if (sceneIn) {
236
- this.removeActiveScene(sceneIn);
237
- const oldScene = currentScene;
238
- currentScene = sceneIn;
239
- if (oldScene) {
240
- oldScene.setInteractiveControlEnable(false);
241
- }
242
- currentScene.setInteractiveControlEnable(true);
243
- currentScene.setAdditionalScenesGroup(scenesGroup);
244
- needsRender = true;
245
- this.onWindowResize();
246
- }
247
- }
233
+ /**
234
+ * Set the current scene on display.
235
+ *
236
+ * @param {Zinc.Scene} sceneIn - The scene to be set, only scene created by this instance
237
+ * of ZincRenderer is supported currently.
238
+ */
239
+ this.setCurrentScene = (sceneIn) => {
240
+ if (sceneIn) {
241
+ this.removeActiveScene(sceneIn);
242
+ const oldScene = currentScene;
243
+ currentScene = sceneIn;
244
+ if (oldScene) {
245
+ oldScene.setInteractiveControlEnable(false);
246
+ }
247
+ currentScene.setInteractiveControlEnable(true);
248
+ currentScene.setAdditionalScenesGroup(scenesGroup);
249
+ needsRender = true;
250
+ this.onWindowResize();
251
+ }
252
+ };
248
253
 
249
- /**
250
- * Return scene with the matching name if scene with that name has been created.
251
- *
252
- * @param {String} name - Name to match
253
- * @return {Zinc.Scene}
254
- */
255
- this.getSceneByName = name => {
254
+ /**
255
+ * Return scene with the matching name if scene with that name has been created.
256
+ *
257
+ * @param {String} name - Name to match
258
+ * @return {Zinc.Scene}
259
+ */
260
+ this.getSceneByName = (name) => {
256
261
  return sceneMap[name];
257
- }
262
+ };
258
263
 
259
264
  /*
260
- * Create a new scene with the provided name if scene with the same name exists,
261
- * return undefined.
262
- *
263
- * @param {String} name - Name of the scene to be created.
264
- * @return {Zinc.Scene}
265
- */
266
- this.createScene = name => {
267
- if (sceneMap[name] != undefined){
268
- return undefined;
269
- } else {
270
- let new_scene = undefined;
271
- if (canvas)
272
- new_scene = new Scene(canvas, renderer);
273
- else
274
- new_scene = new Scene(container, renderer);
275
- sceneMap[name] = new_scene;
276
- new_scene.sceneName = name;
277
- return new_scene;
278
- }
279
- }
280
-
281
- const updateOrthoScene = () => {
282
- if (logoSprite != undefined) {
283
- const material = logoSprite.material;
284
- if (material.map) {
285
- const width = this.getDrawingWidth();
286
- const height = this.getDrawingHeight();
287
- const calculatedWidth = (width - material.map.image.width)/2;
288
- const calculatedHeight = (-height + material.map.image.height)/2;
289
- logoSprite.position.set(calculatedWidth, calculatedHeight, 1 );
290
- }
291
- }
292
- return sceneMap[name];
293
- }
265
+ * Create a new scene with the provided name if scene with the same name exists,
266
+ * return undefined.
267
+ *
268
+ * @param {String} name - Name of the scene to be created.
269
+ * @return {Zinc.Scene}
270
+ */
271
+ this.createScene = (name) => {
272
+ if (sceneMap[name] != undefined) {
273
+ return undefined;
274
+ } else {
275
+ let new_scene = undefined;
276
+ if (canvas) new_scene = new Scene(canvas, renderer);
277
+ else new_scene = new Scene(container, renderer);
278
+ sceneMap[name] = new_scene;
279
+ new_scene.sceneName = name;
280
+ return new_scene;
281
+ }
282
+ };
283
+
284
+ const updateOrthoScene = () => {
285
+ if (logoSprite != undefined) {
286
+ const material = logoSprite.material;
287
+ if (material.map) {
288
+ const width = this.getDrawingWidth();
289
+ const height = this.getDrawingHeight();
290
+ const calculatedWidth = (width - material.map.image.width) / 2;
291
+ const calculatedHeight = (-height + material.map.image.height) / 2;
292
+ logoSprite.position.set(calculatedWidth, calculatedHeight, 1);
293
+ }
294
+ }
295
+ return sceneMap[name];
296
+ };
294
297
 
295
- /**
298
+ /**
296
299
  };
297
300
 
298
301
  const updateOrthoCamera = () => {
@@ -310,445 +313,450 @@ const Renderer = function (containerIn) {
310
313
  /**
311
314
  * Reset the viewport of the current scene to its original state.
312
315
  */
313
- this.resetView = () => {
314
- currentScene.resetView();
315
- }
316
+ this.resetView = () => {
317
+ currentScene.resetView();
318
+ };
316
319
 
317
- /**
318
- * Adjust zoom distance to include all primitives in scene and also the additional scenes
319
- * but the lookat direction and up vectors will remain constant.
320
- */
321
- this.viewAll = () => {
322
- if (currentScene) {
323
- const boundingBox = currentScene.getBoundingBox();
324
- if (boundingBox) {
325
- for(let i = 0; i < additionalActiveScenes.length; i++) {
326
- const boundingBox2 = additionalActiveScenes[i].getBoundingBox();
327
- if (boundingBox2) {
328
- boundingBox.union(boundingBox2);
329
- }
330
- }
331
- currentScene.viewAllWithBoundingBox(boundingBox);
332
- }
333
- }
334
- }
320
+ /**
321
+ * Adjust zoom distance to include all primitives in scene and also the additional scenes
322
+ * but the lookat direction and up vectors will remain constant.
323
+ */
324
+ this.viewAll = () => {
325
+ if (currentScene) {
326
+ const boundingBox = currentScene.getBoundingBox();
327
+ if (boundingBox) {
328
+ for (let i = 0; i < additionalActiveScenes.length; i++) {
329
+ const boundingBox2 = additionalActiveScenes[i].getBoundingBox();
330
+ if (boundingBox2) {
331
+ boundingBox.union(boundingBox2);
332
+ }
333
+ }
334
+ currentScene.viewAllWithBoundingBox(boundingBox);
335
+ }
336
+ }
337
+ };
335
338
 
336
- /**
337
- * Load a legacy model(s) format with the provided URLs and parameters. This only loads the geometry
338
- * without any of the metadata. Therefore, extra parameters should be provided. This should be
339
- * called from {@link Zinc.Scene}.
340
- *
341
- * @deprecated
342
- */
343
- this.loadModelsURL = (urls, colours, opacities, timeEnabled, morphColour, finishCallback) => {
344
- currentScene.loadModelsURL(urls, colours, opacities, timeEnabled, morphColour, finishCallback);
345
- }
339
+ /**
340
+ * Load a legacy model(s) format with the provided URLs and parameters. This only loads the geometry
341
+ * without any of the metadata. Therefore, extra parameters should be provided. This should be
342
+ * called from {@link Zinc.Scene}.
343
+ *
344
+ * @deprecated
345
+ */
346
+ this.loadModelsURL = (urls, colours, opacities, timeEnabled, morphColour, finishCallback) => {
347
+ currentScene.loadModelsURL(urls, colours, opacities, timeEnabled, morphColour, finishCallback);
348
+ };
346
349
 
347
- const loadView = viewData => {
348
- currentScene.loadView(viewData);
349
- };
350
+ const loadView = (viewData) => {
351
+ currentScene.loadView(viewData);
352
+ };
350
353
 
351
- /**
352
- * Load the viewport from an external location provided by the url. This should be
353
- * called from {@link Zinc.Scene};
354
- * @param {String} URL - address to the file containing viewport information.
355
- * @deprecated
356
- */
357
- this.loadViewURL = url => {
358
- currentScene.loadViewURL(url);
359
- }
354
+ /**
355
+ * Load the viewport from an external location provided by the url. This should be
356
+ * called from {@link Zinc.Scene};
357
+ * @param {String} URL - address to the file containing viewport information.
358
+ * @deprecated
359
+ */
360
+ this.loadViewURL = (url) => {
361
+ currentScene.loadViewURL(url);
362
+ };
360
363
 
361
- /**
362
- * Load a legacy file format containing the viewport and its model file from an external
363
- * location provided by the url. Use the new metadata format with
364
- * {@link Zinc.Scene#loadMetadataURL} instead. This should be
365
- * called from {@link Zinc.Scene};
366
- *
367
- * @param {String} URL - address to the file containing viewport and model information.
368
- * @deprecated
369
- */
370
- this.loadFromViewURL = (jsonFilePrefix, finishCallback) => {
371
- currentScene.loadFromViewURL(jsonFilePrefix, finishCallback);
372
- }
364
+ /**
365
+ * Load a legacy file format containing the viewport and its model file from an external
366
+ * location provided by the url. Use the new metadata format with
367
+ * {@link Zinc.Scene#loadMetadataURL} instead. This should be
368
+ * called from {@link Zinc.Scene};
369
+ *
370
+ * @param {String} URL - address to the file containing viewport and model information.
371
+ * @deprecated
372
+ */
373
+ this.loadFromViewURL = (jsonFilePrefix, finishCallback) => {
374
+ currentScene.loadFromViewURL(jsonFilePrefix, finishCallback);
375
+ };
373
376
 
374
- this.updateDirectionalLight = () => {
375
- currentScene.updateDirectionalLight();
376
- }
377
+ this.updateDirectionalLight = () => {
378
+ currentScene.updateDirectionalLight();
379
+ };
377
380
 
378
381
  let runAnimation = () => {
379
382
  if (isRendering) {
380
- animated_id = requestAnimationFrame( runAnimation );
383
+ animated_id = requestAnimationFrame(runAnimation);
381
384
  this.render();
382
385
  } else {
383
386
  cancelAnimationFrame(animated_id);
384
387
  animated_id = undefined;
385
388
  }
386
- }
389
+ };
387
390
 
388
- /**
389
- * Stop the animation and renderer to get into the render loop.
390
- */
391
- this.stopAnimate = () => {
391
+ /**
392
+ * Stop the animation and renderer to get into the render loop.
393
+ */
394
+ this.stopAnimate = () => {
392
395
  if (isRendering) {
393
396
  isRendering = false;
394
397
  }
395
- }
398
+ };
396
399
 
397
- /**
398
- * Start the animation and begin the rendering loop.
399
- */
400
- this.animate = () => {
400
+ /**
401
+ * Start the animation and begin the rendering loop.
402
+ */
403
+ this.animate = () => {
401
404
  if (!isRendering) {
402
405
  clock.reset();
403
406
  isRendering = true;
404
407
  needsRender = true;
405
408
  runAnimation();
406
409
  }
407
- }
410
+ };
408
411
 
409
- const prevTime = Date.now();
412
+ const prevTime = Date.now();
410
413
 
411
- /**
412
- * Add a callback function which will be called when the gl context is lost.
413
- * @param {Function} callbackFunction - callbackFunction to be added.
414
- *
415
- * @return {Number}
416
- */
417
- this.addContextLostCallbackFunction = callbackFunction => {
418
- contextLostCallbackFunctions_id = contextLostCallbackFunctions_id + 1;
419
- contextLostCallbackFunctions[contextLostCallbackFunctions_id] = callbackFunction;
420
- return contextLostCallbackFunctions_id;
421
- }
422
-
423
- /**
424
- * Remove a callback function that is previously added to the renderer.
425
- * @param {Number} id - identifier of the previously added callback function.
426
- */
427
- this.removeContextLostCallbackFunction = id => {
428
- if (id in contextLostCallbackFunctions) {
429
- delete contextLostCallbackFunctions[id];
430
- }
431
- }
432
-
433
- /**
434
- * Add a callback function which will be called when the gl context is restored.
435
- * @param {Function} callbackFunction - callbackFunction to be added.
436
- *
437
- * @return {Number}
438
- */
439
- this.addContextRestoredCallbackFunction = callbackFunction => {
440
- contextRestoredCallbackFunctions_id = contextRestoredCallbackFunctions_id + 1;
441
- contextRestoredCallbackFunctions[contextRestoredCallbackFunctions_id] = callbackFunction;
442
- return contextRestoredCallbackFunctions_id;
443
- }
414
+ /**
415
+ * Add a callback function which will be called when the gl context is lost.
416
+ * @param {Function} callbackFunction - callbackFunction to be added.
417
+ *
418
+ * @return {Number}
419
+ */
420
+ this.addContextLostCallbackFunction = (callbackFunction) => {
421
+ contextLostCallbackFunctions_id = contextLostCallbackFunctions_id + 1;
422
+ contextLostCallbackFunctions[contextLostCallbackFunctions_id] = callbackFunction;
423
+ return contextLostCallbackFunctions_id;
424
+ };
444
425
 
445
- /**
446
- * Remove a callback function that is previously added to the renderer.
447
- * @param {Number} id - identifier of the previously added callback function.
448
- */
449
- this.removeContextRestoredCallbackFunction = id => {
450
- if (id in contextRestoredCallbackFunctions_id) {
451
- delete contextRestoredCallbackFunctions_id[id];
452
- }
453
- }
426
+ /**
427
+ * Remove a callback function that is previously added to the renderer.
428
+ * @param {Number} id - identifier of the previously added callback function.
429
+ */
430
+ this.removeContextLostCallbackFunction = (id) => {
431
+ if (id in contextLostCallbackFunctions) {
432
+ delete contextLostCallbackFunctions[id];
433
+ }
434
+ };
454
435
 
455
- /**
456
- * Add a callback function which will be called everytime before the renderer renders its scene.
457
- * @param {Function} callbackFunction - callbackFunction to be added.
458
- *
459
- * @return {Number}
460
- */
461
- this.addPreRenderCallbackFunction = callbackFunction => {
462
- preRenderCallbackFunctions_id = preRenderCallbackFunctions_id + 1;
463
- preRenderCallbackFunctions[preRenderCallbackFunctions_id] = callbackFunction;
464
- return preRenderCallbackFunctions_id;
465
- }
436
+ /**
437
+ * Add a callback function which will be called when the gl context is restored.
438
+ * @param {Function} callbackFunction - callbackFunction to be added.
439
+ *
440
+ * @return {Number}
441
+ */
442
+ this.addContextRestoredCallbackFunction = (callbackFunction) => {
443
+ contextRestoredCallbackFunctions_id = contextRestoredCallbackFunctions_id + 1;
444
+ contextRestoredCallbackFunctions[contextRestoredCallbackFunctions_id] = callbackFunction;
445
+ return contextRestoredCallbackFunctions_id;
446
+ };
466
447
 
467
- /**
468
- * Remove a callback function that is previously added to the scene.
469
- * @param {Number} id - identifier of the previously added callback function.
470
- */
471
- this.removePreRenderCallbackFunction = id => {
472
- if (id in preRenderCallbackFunctions) {
473
- delete preRenderCallbackFunctions[id];
474
- }
475
- }
448
+ /**
449
+ * Remove a callback function that is previously added to the renderer.
450
+ * @param {Number} id - identifier of the previously added callback function.
451
+ */
452
+ this.removeContextRestoredCallbackFunction = (id) => {
453
+ if (id in contextRestoredCallbackFunctions_id) {
454
+ delete contextRestoredCallbackFunctions_id[id];
455
+ }
456
+ };
476
457
 
477
- /**
478
- * Add a callback function which will be called everytime after the renderer renders its scene.
479
- * @param {Function} callbackFunction - callbackFunction to be added.
480
- *
481
- * @return {Number}
482
- */
483
- this.addPostRenderCallbackFunction = callbackFunction => {
484
- postRenderCallbackFunctions_id = postRenderCallbackFunctions_id + 1;
485
- postRenderCallbackFunctions[postRenderCallbackFunctions_id] = callbackFunction;
486
- return postRenderCallbackFunctions_id;
487
- }
458
+ /**
459
+ * Add a callback function which will be called everytime before the renderer renders its scene.
460
+ * @param {Function} callbackFunction - callbackFunction to be added.
461
+ *
462
+ * @return {Number}
463
+ */
464
+ this.addPreRenderCallbackFunction = (callbackFunction) => {
465
+ preRenderCallbackFunctions_id = preRenderCallbackFunctions_id + 1;
466
+ preRenderCallbackFunctions[preRenderCallbackFunctions_id] = callbackFunction;
467
+ return preRenderCallbackFunctions_id;
468
+ };
488
469
 
489
- /**
490
- * Remove a callback function that is previously added to the scene.
491
- * @param {Number} id - identifier of the previously added callback function.
492
- */
493
- this.removePostRenderCallbackFunction = id => {
494
- if (id in postRenderCallbackFunctions) {
495
- delete postRenderCallbackFunctions[id];
496
- }
497
- }
470
+ /**
471
+ * Remove a callback function that is previously added to the scene.
472
+ * @param {Number} id - identifier of the previously added callback function.
473
+ */
474
+ this.removePreRenderCallbackFunction = (id) => {
475
+ if (id in preRenderCallbackFunctions) {
476
+ delete preRenderCallbackFunctions[id];
477
+ }
478
+ };
498
479
 
499
- /**
500
- * Get the current play rate, playrate affects how fast an animated object animates.
501
- * Also see {@link Zinc.Scene#duration}.
502
- */
503
- this.getPlayRate = () => {
504
- return playRate;
505
- }
480
+ /**
481
+ * Add a callback function which will be called everytime after the renderer renders its scene.
482
+ * @param {Function} callbackFunction - callbackFunction to be added.
483
+ *
484
+ * @return {Number}
485
+ */
486
+ this.addPostRenderCallbackFunction = (callbackFunction) => {
487
+ postRenderCallbackFunctions_id = postRenderCallbackFunctions_id + 1;
488
+ postRenderCallbackFunctions[postRenderCallbackFunctions_id] = callbackFunction;
489
+ return postRenderCallbackFunctions_id;
490
+ };
506
491
 
507
- /**
508
- * Set the current play rate, playrate affects how fast an animated object animates.
509
- * @param {Number} PlayRateIn - value to set the playrate to.
510
- * Also see {@link Zinc.Scene#duration}.
511
- */
512
- this.setPlayRate = playRateIn => {
513
- playRate = playRateIn;
514
- needsRender = true;
515
- }
492
+ /**
493
+ * Remove a callback function that is previously added to the scene.
494
+ * @param {Number} id - identifier of the previously added callback function.
495
+ */
496
+ this.removePostRenderCallbackFunction = (id) => {
497
+ if (id in postRenderCallbackFunctions) {
498
+ delete postRenderCallbackFunctions[id];
499
+ }
500
+ };
516
501
 
517
- /**
518
- * Enable or disable render on demand, it is disabled by default.
519
- * When enabled, the scenes are only drawn when something has changed,
520
- * e.g. camera movement, animation, loading and changes made through
521
- * the Zinc APIs. Call {@link Renderer#invalidate} after modifying
522
- * THREE.js objects directly or after changing the THREE.js renderer,
523
- * e.g. setClearColor.
524
- * Pre-render callbacks are called on every frame, post-render callbacks
525
- * are only called when the scenes are drawn.
526
- *
527
- * @param {Boolean} flag - Enable or disable render on demand.
528
- */
529
- this.setRenderOnDemand = flag => {
530
- renderOnDemand = flag ? true : false;
531
- needsRender = true;
532
- }
502
+ /**
503
+ * Get the current play rate, playrate affects how fast an animated object animates.
504
+ * Also see {@link Zinc.Scene#duration}.
505
+ */
506
+ this.getPlayRate = () => {
507
+ return playRate;
508
+ };
533
509
 
534
- /**
535
- * Check if render on demand is enabled.
536
- *
537
- * @return {Boolean}
538
- */
539
- this.isRenderOnDemand = () => {
540
- return renderOnDemand;
541
- }
510
+ /**
511
+ * Set the current play rate, playrate affects how fast an animated object animates.
512
+ * @param {Number} PlayRateIn - value to set the playrate to.
513
+ * Also see {@link Zinc.Scene#duration}.
514
+ */
515
+ this.setPlayRate = (playRateIn) => {
516
+ playRate = playRateIn;
517
+ needsRender = true;
518
+ };
542
519
 
543
- /**
544
- * Request the scenes to be drawn on the next frame, this is only
545
- * required when render on demand is enabled.
546
- */
547
- this.invalidate = () => {
548
- needsRender = true;
549
- }
520
+ /**
521
+ * Enable or disable render on demand, it is disabled by default.
522
+ * When enabled, the scenes are only drawn when something has changed,
523
+ * e.g. camera movement, animation, loading and changes made through
524
+ * the Zinc APIs. Call {@link Renderer#invalidate} after modifying
525
+ * THREE.js objects directly or after changing the THREE.js renderer,
526
+ * e.g. setClearColor.
527
+ * Pre-render callbacks are called on every frame, post-render callbacks
528
+ * are only called when the scenes are drawn.
529
+ *
530
+ * @param {Boolean} flag - Enable or disable render on demand.
531
+ */
532
+ this.setRenderOnDemand = (flag) => {
533
+ renderOnDemand = flag ? true : false;
534
+ needsRender = true;
535
+ };
550
536
 
551
- this.getCurrentTime = () => {
552
- return currentScene.getCurrentTime();
553
- }
537
+ /**
538
+ * Check if render on demand is enabled.
539
+ *
540
+ * @return {Boolean}
541
+ */
542
+ this.isRenderOnDemand = () => {
543
+ return renderOnDemand;
544
+ };
554
545
 
546
+ /**
547
+ * Request the scenes to be drawn on the next frame, this is only
548
+ * required when render on demand is enabled.
549
+ */
550
+ this.invalidate = () => {
551
+ needsRender = true;
552
+ };
555
553
 
556
- /**
557
- * Get the current play rate, playrate affects how fast an animated object animates.
558
- * Also see {@link Zinc.Scene#duration}.
559
- */
560
- this.setMorphsTime = time => {
561
- currentScene.setMorphsTime(time);
562
- }
554
+ this.getCurrentTime = () => {
555
+ return currentScene.getCurrentTime();
556
+ };
563
557
 
564
- /**
565
- * Get {Zinc.Geoemtry} by its id. This should be called from {@link Zinc.Scene};
566
- *
567
- * @depreacted
568
- * @return {Zinc.Geometry}
569
- */
570
- this.getZincGeometryByID = id => {
571
- return currentScene.getZincGeometryByID(id);
572
- }
558
+ /**
559
+ * Get the current play rate, playrate affects how fast an animated object animates.
560
+ * Also see {@link Zinc.Scene#duration}.
561
+ */
562
+ this.setMorphsTime = (time) => {
563
+ currentScene.setMorphsTime(time);
564
+ };
573
565
 
574
- /**
575
- * Add {Three.Object} to the current scene.
576
- */
577
- this.addToScene = object => {
578
- currentScene.addObject(object)
579
- }
566
+ /**
567
+ * Get {Zinc.Geoemtry} by its id. This should be called from {@link Zinc.Scene};
568
+ *
569
+ * @depreacted
570
+ * @return {Zinc.Geometry}
571
+ */
572
+ this.getZincGeometryByID = (id) => {
573
+ return currentScene.getZincGeometryByID(id);
574
+ };
580
575
 
581
- /**
582
- * Add {Three.Object} to the ortho scene, objects added to the ortho scene are rendered in
583
- * normalised coordinates and overlay on top of current scene.
584
- *
585
- */
586
- this.addToOrthoScene = object => {
587
- if (sceneOrtho == undefined)
588
- sceneOrtho = new THREE.Scene();
589
- if (cameraOrtho == undefined) {
590
- const width = this.getDrawingWidth();
591
- const height = this.getDrawingHeight();
592
- cameraOrtho = new THREE.OrthographicCamera( -width / 2,
593
- width / 2, height/ 2, -height / 2, 1, 10 );
594
- cameraOrtho.position.z = 10;
595
- }
596
- sceneOrtho.add(object)
597
- needsRender = true;
598
- }
599
-
600
- const createHUDSprites = logoSprite => {
601
- return texture => {
602
- texture.needsUpdate = true;
603
- const material = new THREE.SpriteMaterial( { map: texture } );
604
- const imagewidth = material.map.image.width;
605
- const imageheight = material.map.image.height;
606
- logoSprite.material = material;
607
- logoSprite.scale.set( imagewidth, imageheight, 1 );
608
- const width = this.getDrawingWidth();
609
- const height = this.getDrawingHeight();
610
- logoSprite.position.set( (width - imagewidth)/2, (-height + imageheight)/2, 1 );
611
- this.addToOrthoScene(logoSprite);
612
- };
613
- };
576
+ /**
577
+ * Add {Three.Object} to the current scene.
578
+ */
579
+ this.addToScene = (object) => {
580
+ currentScene.addObject(object);
581
+ };
614
582
 
615
- this.addLogo = () => {
616
- logoSprite = new THREE.Sprite();
617
- const logo = THREE.ImageUtils.loadTexture(
618
- "images/abi_big_logo_transparent_small.png", undefined, createHUDSprites(logoSprite));
619
- }
583
+ /**
584
+ * Add {Three.Object} to the ortho scene, objects added to the ortho scene are rendered in
585
+ * normalised coordinates and overlay on top of current scene.
586
+ *
587
+ */
588
+ this.addToOrthoScene = (object) => {
589
+ if (sceneOrtho == undefined) sceneOrtho = new THREE.Scene();
590
+ if (cameraOrtho == undefined) {
591
+ const width = this.getDrawingWidth();
592
+ const height = this.getDrawingHeight();
593
+ cameraOrtho = new THREE.OrthographicCamera(
594
+ -width / 2,
595
+ width / 2,
596
+ height / 2,
597
+ -height / 2,
598
+ 1,
599
+ 10,
600
+ );
601
+ cameraOrtho.position.z = 10;
602
+ }
603
+ sceneOrtho.add(object);
604
+ needsRender = true;
605
+ };
606
+
607
+ const createHUDSprites = (logoSprite) => {
608
+ return (texture) => {
609
+ texture.needsUpdate = true;
610
+ const material = new THREE.SpriteMaterial({ map: texture });
611
+ const imagewidth = material.map.image.width;
612
+ const imageheight = material.map.image.height;
613
+ logoSprite.material = material;
614
+ logoSprite.scale.set(imagewidth, imageheight, 1);
615
+ const width = this.getDrawingWidth();
616
+ const height = this.getDrawingHeight();
617
+ logoSprite.position.set((width - imagewidth) / 2, (-height + imageheight) / 2, 1);
618
+ this.addToOrthoScene(logoSprite);
619
+ };
620
+ };
621
+
622
+ this.addLogo = () => {
623
+ logoSprite = new THREE.Sprite();
624
+ const logo = THREE.ImageUtils.loadTexture(
625
+ 'images/abi_big_logo_transparent_small.png',
626
+ undefined,
627
+ createHUDSprites(logoSprite),
628
+ );
629
+ };
620
630
 
621
- /**
622
- * Render the current and all additional scenes. It will first update all geometries and glyphsets
623
- * in scenes, clear depth buffer and render the ortho scene, call the preRenderCallbackFunctions stack
624
- * , render the scenes then postRenderCallback.
625
- */
626
- this.render = () => {
627
- if (!sensor) {
628
- if (container) {
629
- if (container.clientWidth > 0 && container.clientHeight > 0) {
630
- sensor = new ResizeSensor(container, this.onWindowResize);
631
- }
632
- } else if (canvas) {
633
- if (canvas.width > 0 && canvas.height > 0)
634
- sensor = new ResizeSensor(canvas, this.onWindowResize);
635
- }
636
- }
631
+ /**
632
+ * Render the current and all additional scenes. It will first update all geometries and glyphsets
633
+ * in scenes, clear depth buffer and render the ortho scene, call the preRenderCallbackFunctions stack
634
+ * , render the scenes then postRenderCallback.
635
+ */
636
+ this.render = () => {
637
+ if (!sensor) {
638
+ if (container) {
639
+ if (container.clientWidth > 0 && container.clientHeight > 0) {
640
+ sensor = new ResizeSensor(container, this.onWindowResize);
641
+ }
642
+ } else if (canvas) {
643
+ if (canvas.width > 0 && canvas.height > 0)
644
+ sensor = new ResizeSensor(canvas, this.onWindowResize);
645
+ }
646
+ }
637
647
  clock.update();
638
- const delta = clock.getDelta();
639
- let changed = currentScene.renderGeometries(playRate, delta, this.playAnimation);
640
- if (additionalActiveScenes.length > 0) {
641
- //Additional scenes are displayed with the current scene's camera
642
- sharedCamera.controls = currentScene.getZincCameraControls();
643
- sharedCamera.updated = currentScene.isCameraUpdated();
644
- }
645
- for(let i = 0; i < additionalActiveScenes.length; i++) {
646
- const sceneItem = additionalActiveScenes[i];
647
- if (sceneItem.renderGeometries(playRate, delta, this.playAnimation, sharedCamera))
648
- changed = true;
649
- }
648
+ const delta = clock.getDelta();
649
+ let changed = currentScene.renderGeometries(playRate, delta, this.playAnimation);
650
+ if (additionalActiveScenes.length > 0) {
651
+ //Additional scenes are displayed with the current scene's camera
652
+ sharedCamera.controls = currentScene.getZincCameraControls();
653
+ sharedCamera.updated = currentScene.isCameraUpdated();
654
+ }
655
+ for (let i = 0; i < additionalActiveScenes.length; i++) {
656
+ const sceneItem = additionalActiveScenes[i];
657
+ if (sceneItem.renderGeometries(playRate, delta, this.playAnimation, sharedCamera))
658
+ changed = true;
659
+ }
650
660
  for (let key in preRenderCallbackFunctions) {
651
661
  if (preRenderCallbackFunctions.hasOwnProperty(key)) {
652
662
  preRenderCallbackFunctions[key].call();
653
663
  }
654
664
  }
655
- //Pre-render callbacks may have requested a frame
656
- if (renderOnDemand && !changed && !needsRender) {
657
- return;
658
- }
659
- needsRender = false;
665
+ //Pre-render callbacks may have requested a frame
666
+ if (renderOnDemand && !changed && !needsRender) {
667
+ return;
668
+ }
669
+ needsRender = false;
660
670
  currentScene.render(renderer);
661
- if (cameraOrtho != undefined && sceneOrtho != undefined) {
662
- renderer.clearDepth();
663
- renderer.render( sceneOrtho, cameraOrtho );
664
- }
671
+ if (cameraOrtho != undefined && sceneOrtho != undefined) {
672
+ renderer.clearDepth();
673
+ renderer.render(sceneOrtho, cameraOrtho);
674
+ }
665
675
  for (let key in postRenderCallbackFunctions) {
666
676
  if (postRenderCallbackFunctions.hasOwnProperty(key)) {
667
677
  postRenderCallbackFunctions[key].call();
668
678
  }
669
679
  }
670
- }
680
+ };
671
681
 
672
- this.forceContextLoss = () => {
673
- // renderer.forceContextLoss();
674
- }
682
+ this.forceContextLoss = () => {
683
+ // renderer.forceContextLoss();
684
+ };
675
685
 
676
- this.forceContextRestore= () => {
677
- // renderer.forceContextRestore();
678
- }
686
+ this.forceContextRestore = () => {
687
+ // renderer.forceContextRestore();
688
+ };
679
689
 
680
- /**
681
- * Get the internal {@link Three.Renderer}, to gain access to ThreeJS APIs.
682
- */
683
- this.getThreeJSRenderer = () => {
684
- return renderer;
685
- }
690
+ /**
691
+ * Get the internal {@link Three.Renderer}, to gain access to ThreeJS APIs.
692
+ */
693
+ this.getThreeJSRenderer = () => {
694
+ return renderer;
695
+ };
686
696
 
687
- /**
688
- * Check if a scene is currently active.
689
- * @param {Zinc.Scene} sceneIn - Scene to check if it is currently
690
- * rendered.
691
- */
692
- this.isSceneActive = sceneIn => {
693
- if (currentScene === sceneIn) {
694
- return true;
695
- } else {
696
- for(let i = 0; i < additionalActiveScenes.length; i++) {
697
- const sceneItem = additionalActiveScenes[i];
698
- if (sceneItem === sceneIn)
699
- return true;
700
- }
701
- }
702
- return false;
703
- }
697
+ /**
698
+ * Check if a scene is currently active.
699
+ * @param {Zinc.Scene} sceneIn - Scene to check if it is currently
700
+ * rendered.
701
+ */
702
+ this.isSceneActive = (sceneIn) => {
703
+ if (currentScene === sceneIn) {
704
+ return true;
705
+ } else {
706
+ for (let i = 0; i < additionalActiveScenes.length; i++) {
707
+ const sceneItem = additionalActiveScenes[i];
708
+ if (sceneItem === sceneIn) return true;
709
+ }
710
+ }
711
+ return false;
712
+ };
704
713
 
705
- /**
706
- * Add additional active scene for rendering, this scene will also be rendered but
707
- * viewport of the currentScene will be used.
708
- * @param {Zinc.Scene} additionalScene - Scene to be added to the rendering.
709
- */
710
- this.addActiveScene = additionalScene => {
711
- if (!this.isSceneActive(additionalScene)) {
712
- additionalActiveScenes.push(additionalScene);
713
- scenesGroup.add(additionalScene.getThreeJSScene());
714
- needsRender = true;
715
- }
716
- }
714
+ /**
715
+ * Add additional active scene for rendering, this scene will also be rendered but
716
+ * viewport of the currentScene will be used.
717
+ * @param {Zinc.Scene} additionalScene - Scene to be added to the rendering.
718
+ */
719
+ this.addActiveScene = (additionalScene) => {
720
+ if (!this.isSceneActive(additionalScene)) {
721
+ additionalActiveScenes.push(additionalScene);
722
+ scenesGroup.add(additionalScene.getThreeJSScene());
723
+ needsRender = true;
724
+ }
725
+ };
717
726
 
718
- /**
719
- * Remove a currenrtly active scene from the renderer, this scene will also be rendered but
720
- * viewport of the currentScene will be used.
721
- * @param {Zinc.Scene} additionalScene - Scene to be removed from rendering.
722
- */
723
- this.removeActiveScene = additionalScene => {
724
- for(let i = 0; i < additionalActiveScenes.length; i++) {
725
- const sceneItem = additionalActiveScenes[i];
726
- if (sceneItem === additionalScene) {
727
- additionalActiveScenes.splice(i, 1);
728
- scenesGroup.remove(additionalScene.getThreeJSScene());
729
- needsRender = true;
730
- return;
731
- }
732
- }
733
- }
727
+ /**
728
+ * Remove a currenrtly active scene from the renderer, this scene will also be rendered but
729
+ * viewport of the currentScene will be used.
730
+ * @param {Zinc.Scene} additionalScene - Scene to be removed from rendering.
731
+ */
732
+ this.removeActiveScene = (additionalScene) => {
733
+ for (let i = 0; i < additionalActiveScenes.length; i++) {
734
+ const sceneItem = additionalActiveScenes[i];
735
+ if (sceneItem === additionalScene) {
736
+ additionalActiveScenes.splice(i, 1);
737
+ scenesGroup.remove(additionalScene.getThreeJSScene());
738
+ needsRender = true;
739
+ return;
740
+ }
741
+ }
742
+ };
734
743
 
735
- /**
736
- * Clear all additional scenes from rendering except for curentScene.
737
- */
738
- this.clearAllActiveScene = () => {
739
- for (let i = 0; i < additionalActiveScenes.length; i++) {
740
- scenesGroup.remove(additionalActiveScenes[i].getThreeJSScene());
741
- }
742
- additionalActiveScenes.splice(0,additionalActiveScenes.length);
743
- needsRender = true;
744
- }
744
+ /**
745
+ * Clear all additional scenes from rendering except for curentScene.
746
+ */
747
+ this.clearAllActiveScene = () => {
748
+ for (let i = 0; i < additionalActiveScenes.length; i++) {
749
+ scenesGroup.remove(additionalActiveScenes[i].getThreeJSScene());
750
+ }
751
+ additionalActiveScenes.splice(0, additionalActiveScenes.length);
752
+ needsRender = true;
753
+ };
745
754
 
746
755
  /**
747
756
  * Dispose all memory allocated, this will effetively destroy all scenes.
748
757
  */
749
758
  this.dispose = () => {
750
- if (isRendering)
751
- cancelAnimationFrame(animated_id);
759
+ if (isRendering) cancelAnimationFrame(animated_id);
752
760
  for (const key in sceneMap) {
753
761
  if (sceneMap.hasOwnProperty(key)) {
754
762
  sceneMap[key].clearAll();
@@ -769,37 +777,44 @@ const Renderer = function (containerIn) {
769
777
  cameraOrtho = undefined;
770
778
  sceneOrtho = undefined;
771
779
  logoSprite = undefined;
772
- const scene = this.createScene("default");
780
+ const scene = this.createScene('default');
773
781
  this.setCurrentScene(scene);
774
782
  sensor = undefined;
775
783
  offRenderRequest(requestRender);
776
784
  renderer?.dispose();
777
- }
785
+ };
778
786
 
779
- /**
780
- * Transition from the current viewport to the endingScene's viewport in the specified duration.
781
- *
782
- * @param {Zinc.Scene} endingScene - Viewport of this scene will be used as the destination.
783
- * @param {Number} duration - Amount of time to transition from current viewport to the
784
- * endingScene's viewport.
785
- */
786
- this.transitionScene = (endingScene, duration) => {
787
- if (currentScene) {
788
- const currentCamera = currentScene.getZincCameraControls();
789
- const boundingBox = endingScene.getBoundingBox();
790
- if (boundingBox) {
791
- const radius = boundingBox.min.distanceTo(boundingBox.max)/2.0;
792
- const centreX = (boundingBox.min.x + boundingBox.max.x) / 2.0;
793
- const centreY = (boundingBox.min.y + boundingBox.max.y) / 2.0;
794
- const centreZ = (boundingBox.min.z + boundingBox.max.z) / 2.0;
795
- const clip_factor = 4.0;
796
- const endingViewport = currentCamera.getViewportFromCentreAndRadius(centreX, centreY, centreZ, radius, 40, radius * clip_factor );
797
- const startingViewport = currentCamera.getCurrentViewport();
798
- currentCamera.cameraTransition(startingViewport, endingViewport, duration);
799
- currentCamera.enableCameraTransition();
800
- }
801
- }
802
- }
787
+ /**
788
+ * Transition from the current viewport to the endingScene's viewport in the specified duration.
789
+ *
790
+ * @param {Zinc.Scene} endingScene - Viewport of this scene will be used as the destination.
791
+ * @param {Number} duration - Amount of time to transition from current viewport to the
792
+ * endingScene's viewport.
793
+ */
794
+ this.transitionScene = (endingScene, duration) => {
795
+ if (currentScene) {
796
+ const currentCamera = currentScene.getZincCameraControls();
797
+ const boundingBox = endingScene.getBoundingBox();
798
+ if (boundingBox) {
799
+ const radius = boundingBox.min.distanceTo(boundingBox.max) / 2.0;
800
+ const centreX = (boundingBox.min.x + boundingBox.max.x) / 2.0;
801
+ const centreY = (boundingBox.min.y + boundingBox.max.y) / 2.0;
802
+ const centreZ = (boundingBox.min.z + boundingBox.max.z) / 2.0;
803
+ const clip_factor = 4.0;
804
+ const endingViewport = currentCamera.getViewportFromCentreAndRadius(
805
+ centreX,
806
+ centreY,
807
+ centreZ,
808
+ radius,
809
+ 40,
810
+ radius * clip_factor,
811
+ );
812
+ const startingViewport = currentCamera.getCurrentViewport();
813
+ currentCamera.cameraTransition(startingViewport, endingViewport, duration);
814
+ currentCamera.enableCameraTransition();
815
+ }
816
+ }
817
+ };
803
818
 
804
819
  /**
805
820
  * Check if the renderer is running on the WebGL 2 fallback backend.
@@ -809,7 +824,7 @@ const Renderer = function (containerIn) {
809
824
  */
810
825
  this.isWebGL2 = () => {
811
826
  return renderer?.backend?.isWebGLBackend === true;
812
- }
827
+ };
813
828
 
814
829
  /**
815
830
  * Check if the renderer is running on the WebGPU backend.
@@ -818,7 +833,7 @@ const Renderer = function (containerIn) {
818
833
  */
819
834
  this.isWebGPU = () => {
820
835
  return renderer?.backend?.isWebGPUBackend === true;
821
- }
836
+ };
822
837
  };
823
838
 
824
- export { Renderer };
839
+ export { Renderer };