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.
- package/build/zinc.frontend.js +1 -1
- package/build/zinc.js +43 -35
- package/build/zinc.js.map +1 -1
- package/package.json +3 -3
- package/src/assets/disc.png +0 -0
- package/src/assets/mapMarker.svg +11 -0
- package/src/controls.js +1594 -0
- package/src/geometryCSG.js +148 -0
- package/src/glyphsetCSG.js +84 -0
- package/src/loaders/GLTFToZincJSLoader.js +85 -0
- package/src/loaders/JSONLoader.js +697 -0
- package/src/loaders/OBJLoader.js +911 -0
- package/src/loaders/STLLoader.js +399 -0
- package/src/loaders/primitivesLoader.js +46 -0
- package/src/minimap.js +82 -0
- package/src/primitives/augmentShader.js +22 -0
- package/src/primitives/geometry.js +109 -0
- package/src/primitives/glyph.js +150 -0
- package/src/primitives/glyphset.js +657 -0
- package/src/primitives/label.js +51 -0
- package/src/primitives/lines.js +35 -0
- package/src/primitives/marker.js +88 -0
- package/src/primitives/pointset.js +53 -0
- package/src/primitives/texturePrimitive.js +16 -0
- package/src/primitives/textureSlides.js +118 -0
- package/src/primitives/zincObject.js +573 -0
- package/src/region.js +554 -0
- package/src/renderer.js +612 -0
- package/src/scene.js +963 -0
- package/src/sceneExporter.js +32 -0
- package/src/sceneLoader.js +842 -0
- package/src/texture/texture.js +57 -0
- package/src/texture/textureArray.js +85 -0
- package/src/three/GLTFExporter.js +2448 -0
- package/src/three/Geometry.js +2084 -0
- package/src/three/Loader.js +344 -0
- package/src/three/Points.js +223 -0
- package/src/three/line/Line.js +293 -0
- package/src/three/line/LineSegments.js +65 -0
- package/src/three-js-csg.js +564 -0
- package/src/utilities.js +321 -0
- package/src/videoHandler.js +92 -0
- package/src/workers/geometryCSG.worker.js +73 -0
- package/src/workers/geometryCSGInternal.js +58 -0
- package/src/zinc.js +38 -0
package/src/scene.js
ADDED
|
@@ -0,0 +1,963 @@
|
|
|
1
|
+
const THREE = require('three');
|
|
2
|
+
const SceneLoader = require('./sceneLoader').SceneLoader;
|
|
3
|
+
const SceneExporter = require('./sceneExporter').SceneExporter;
|
|
4
|
+
const Viewport = require('./controls').Viewport;
|
|
5
|
+
|
|
6
|
+
const defaultMetadata = function() {
|
|
7
|
+
return {
|
|
8
|
+
Duration: "6 secs",
|
|
9
|
+
OriginalDuration: "-",
|
|
10
|
+
TimeStamps: {}
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const defaultDuration = 6000;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A Zinc.Scene contains {@link Zinc.Geometry}, {@link Zinc.Glyphset} and
|
|
18
|
+
* {@link Zinc.CameraControls} which controls the viewport and additional features.
|
|
19
|
+
* It is the main object used for controlling what is and what is not displayed
|
|
20
|
+
* on the renderer.
|
|
21
|
+
*
|
|
22
|
+
* @class
|
|
23
|
+
* @param {Object} containerIn - Container to create the renderer on.
|
|
24
|
+
* @author Alan Wu
|
|
25
|
+
* @return {Zinc.Scene}
|
|
26
|
+
*/
|
|
27
|
+
exports.Scene = function (containerIn, rendererIn) {
|
|
28
|
+
const container = containerIn;
|
|
29
|
+
let videoHandler = undefined;
|
|
30
|
+
let sceneLoader = new SceneLoader(this);
|
|
31
|
+
let minimap = undefined;
|
|
32
|
+
const scene = new THREE.Scene();
|
|
33
|
+
const rootRegion = new (require('./region').Region)();
|
|
34
|
+
scene.add(rootRegion.getGroup());
|
|
35
|
+
/**
|
|
36
|
+
* A {@link THREE.DirectionalLight} object for controlling lighting of this scene.
|
|
37
|
+
*/
|
|
38
|
+
this.directionalLight = undefined;
|
|
39
|
+
/**
|
|
40
|
+
* a {@link THREE.AmbientLight} for controlling the ambient lighting of this scene.
|
|
41
|
+
*/
|
|
42
|
+
this.ambient = undefined;
|
|
43
|
+
this.camera = undefined;
|
|
44
|
+
let duration = 6000;
|
|
45
|
+
let zincCameraControls = undefined;
|
|
46
|
+
this.sceneName = undefined;
|
|
47
|
+
let stereoEffectFlag = false;
|
|
48
|
+
let stereoEffect = undefined;
|
|
49
|
+
this.autoClearFlag = true;
|
|
50
|
+
this.displayMarkers = false;
|
|
51
|
+
this.displayMinimap = false;
|
|
52
|
+
this.minimapScissor = {
|
|
53
|
+
x_offset: 16,
|
|
54
|
+
y_offset: 16,
|
|
55
|
+
width: 128,
|
|
56
|
+
height: 128,
|
|
57
|
+
align: "top-left",
|
|
58
|
+
updateRequired: true
|
|
59
|
+
};
|
|
60
|
+
let scissor = {x: 0, y: 0};
|
|
61
|
+
let metadata = defaultMetadata();
|
|
62
|
+
let _markerTarget = new THREE.Vector2();
|
|
63
|
+
let pickableObjectsList = [];
|
|
64
|
+
this.forcePickableObjectsUpdate = false;
|
|
65
|
+
|
|
66
|
+
const getDrawingWidth = () => {
|
|
67
|
+
if (container)
|
|
68
|
+
if (typeof container.clientWidth !== "undefined")
|
|
69
|
+
return container.clientWidth;
|
|
70
|
+
else
|
|
71
|
+
return container.width;
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
const getDrawingHeight = () => {
|
|
77
|
+
if (container)
|
|
78
|
+
if (typeof container.clientHeight !== "undefined")
|
|
79
|
+
return container.clientHeight;
|
|
80
|
+
else
|
|
81
|
+
return container.height;
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* This function returns a three component array, which contains
|
|
87
|
+
* [totalsize, totalLoaded and errorDownload] of all the downloads happening
|
|
88
|
+
* in this scene.
|
|
89
|
+
* @returns {Array}
|
|
90
|
+
*/
|
|
91
|
+
this.getDownloadProgress = () => {
|
|
92
|
+
return sceneLoader.getDownloadProgress();
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//called from Renderer when panel has been resized
|
|
96
|
+
this.onWindowResize = () => {
|
|
97
|
+
this.camera.aspect = getDrawingWidth() / getDrawingHeight();
|
|
98
|
+
this.camera.updateProjectionMatrix();
|
|
99
|
+
this.minimapScissor.updateRequired = true;
|
|
100
|
+
zincCameraControls.onResize();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Reset the viewport of this scene to its original state.
|
|
105
|
+
*/
|
|
106
|
+
this.resetView = () => {
|
|
107
|
+
this.onWindowResize();
|
|
108
|
+
zincCameraControls.resetView();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Set the zoom level by unit scroll rate
|
|
113
|
+
*/
|
|
114
|
+
this.changeZoomByScrollRateUnit = unit => {
|
|
115
|
+
zincCameraControls.changeZoomByScrollRateUnit(unit);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
//Setup the camera for this scene, it also initialise the lighting
|
|
119
|
+
const setupCamera = () => {
|
|
120
|
+
this.camera = new THREE.PerspectiveCamera(40, getDrawingWidth() / getDrawingHeight(), 0.0, 10.0);
|
|
121
|
+
this.ambient = new THREE.AmbientLight(0xffffff, 0.2);
|
|
122
|
+
scene.add(this.ambient);
|
|
123
|
+
|
|
124
|
+
this.directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
|
125
|
+
scene.add(this.directionalLight);
|
|
126
|
+
zincCameraControls = new (require('./controls').CameraControls)(this.camera, rendererIn.domElement, rendererIn, this);
|
|
127
|
+
|
|
128
|
+
zincCameraControls.setDirectionalLight(this.directionalLight);
|
|
129
|
+
zincCameraControls.resetView();
|
|
130
|
+
|
|
131
|
+
minimap = new (require('./minimap').Minimap)(this);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
setupCamera();
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Load the viewport Data from the argument {@link Zinc.Viewport} and set it as
|
|
138
|
+
* the default viewport of this scene.
|
|
139
|
+
*
|
|
140
|
+
* @param {Zinc.Viewport} viewData - Viewport data to be loaded.
|
|
141
|
+
*/
|
|
142
|
+
this.loadView = settings => {
|
|
143
|
+
const viewPort = new Viewport();
|
|
144
|
+
viewPort.setFromObject(settings);
|
|
145
|
+
zincCameraControls.setCurrentCameraSettings(viewPort);
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Set up multiple views.
|
|
151
|
+
*
|
|
152
|
+
* @param {Zinc.Viewport} viewData - Viewport data to be loaded.
|
|
153
|
+
*/
|
|
154
|
+
this.setupMultipleViews = (defaultView, entries) => {
|
|
155
|
+
for (const [name, settings] of Object.entries(entries)) {
|
|
156
|
+
const viewport = new Viewport();
|
|
157
|
+
viewport.setFromObject(settings);
|
|
158
|
+
zincCameraControls.addViewport(name, viewport);
|
|
159
|
+
}
|
|
160
|
+
zincCameraControls.setDefaultViewport(defaultView);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Get the bounding box of all the object in this scene only.
|
|
165
|
+
*
|
|
166
|
+
* @returns {THREE.Box3}
|
|
167
|
+
*/
|
|
168
|
+
this.getBoundingBox = () => {
|
|
169
|
+
return rootRegion.getBoundingBox(true);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Adjust the viewport to display the desired volume provided by the bounding box.
|
|
174
|
+
*
|
|
175
|
+
* @param {THREE.Box3} boundingBox - The bounding box which describes the volume of
|
|
176
|
+
* which we the viewport should be displaying.
|
|
177
|
+
*/
|
|
178
|
+
this.viewAllWithBoundingBox = boundingBox => {
|
|
179
|
+
if (boundingBox) {
|
|
180
|
+
// enlarge radius to keep image within edge of window
|
|
181
|
+
const radius = boundingBox.min.distanceTo(boundingBox.max) / 2.0;
|
|
182
|
+
const centreX = (boundingBox.min.x + boundingBox.max.x) / 2.0;
|
|
183
|
+
const centreY = (boundingBox.min.y + boundingBox.max.y) / 2.0;
|
|
184
|
+
const centreZ = (boundingBox.min.z + boundingBox.max.z) / 2.0;
|
|
185
|
+
const clip_factor = 4.0;
|
|
186
|
+
const viewport = zincCameraControls.getViewportFromCentreAndRadius(centreX, centreY, centreZ, radius, 40, radius * clip_factor);
|
|
187
|
+
|
|
188
|
+
zincCameraControls.setCurrentCameraSettings(viewport);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Adjust zoom distance to include all primitives in scene only.
|
|
194
|
+
*/
|
|
195
|
+
this.viewAll = () => {
|
|
196
|
+
const boundingBox = this.getBoundingBox();
|
|
197
|
+
this.viewAllWithBoundingBox(boundingBox);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* A function which iterates through the list of geometries and call the callback
|
|
202
|
+
* function with the geometries as the argument.
|
|
203
|
+
* @param {Function} callbackFunction - Callback function with the geometry
|
|
204
|
+
* as an argument.
|
|
205
|
+
*/
|
|
206
|
+
this.forEachGeometry = callbackFunction => {
|
|
207
|
+
rootRegion.forEachGeometry(callbackFunction, true);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* A function which iterates through the list of glyphsets and call the callback
|
|
212
|
+
* function with the glyphset as the argument.
|
|
213
|
+
* @param {Function} callbackFunction - Callback function with the glyphset
|
|
214
|
+
* as an argument.
|
|
215
|
+
*/
|
|
216
|
+
this.forEachGlyphset = callbackFunction => {
|
|
217
|
+
rootRegion.forEachGlyphset(callbackFunction, true);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* A function which iterates through the list of pointsets and call the callback
|
|
222
|
+
* function with the pointset as the argument.
|
|
223
|
+
* @param {Function} callbackFunction - Callback function with the pointset
|
|
224
|
+
* as an argument.
|
|
225
|
+
*/
|
|
226
|
+
this.forEachPointset = callbackFunction => {
|
|
227
|
+
rootRegion.forEachPointset(callbackFunction, true);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* A function which iterates through the list of lines and call the callback
|
|
232
|
+
* function with the lines as the argument.
|
|
233
|
+
* @param {Function} callbackFunction - Callback function with the lines
|
|
234
|
+
* as an argument.
|
|
235
|
+
*/
|
|
236
|
+
this.forEachLine = callbackFunction => {
|
|
237
|
+
rootRegion.forEachLine(callbackFunction, true);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Find and return all geometries in this scene with the matching GroupName.
|
|
242
|
+
*
|
|
243
|
+
* @param {String} GroupName - Groupname to match with.
|
|
244
|
+
* @returns {Array}
|
|
245
|
+
*/
|
|
246
|
+
this.findGeometriesWithGroupName = GroupName => {
|
|
247
|
+
return rootRegion.findGeometriesWithGroupName(GroupName, true);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Find and return all pointsets in this scene with the matching GroupName.
|
|
252
|
+
*
|
|
253
|
+
* @param {String} GroupName - Groupname to match with.
|
|
254
|
+
* @returns {Array}
|
|
255
|
+
*/
|
|
256
|
+
this.findPointsetsWithGroupName = GroupName => {
|
|
257
|
+
return rootRegion.findPointsetsWithGroupName(GroupName, true);
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Find and return all glyphsets in this scene with the matching GroupName.
|
|
261
|
+
*
|
|
262
|
+
* @param {String} GroupName - Groupname to match with.
|
|
263
|
+
* @returns {Array}
|
|
264
|
+
*/
|
|
265
|
+
this.findGlyphsetsWithGroupName = GroupName => {
|
|
266
|
+
return rootRegion.findGlyphsetsWithGroupName(GroupName, true);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Find and return all lines in this scene with the matching GroupName.
|
|
271
|
+
*
|
|
272
|
+
* @param {String} GroupName - Groupname to match with.
|
|
273
|
+
* @returns {Array}
|
|
274
|
+
*/
|
|
275
|
+
this.findLinesWithGroupName = GroupName => {
|
|
276
|
+
return rootRegion.findLinesWithGroupName(GroupName, true);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
this.findObjectsWithGroupName = GroupName => {
|
|
280
|
+
return rootRegion.findObjectsWithGroupName(GroupName, true);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
this.findObjectsWithAnatomicalId = anatomicalId => {
|
|
284
|
+
return rootRegion.findObjectsWithAnatomicalId(anatomicalId, true);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
this.getBoundingBoxOfZincObjects = objectsArray => {
|
|
288
|
+
let boundingBox = undefined;
|
|
289
|
+
for (let i = 0; i < objectsArray.length; i++) {
|
|
290
|
+
let box = objectsArray[i].getBoundingBox();
|
|
291
|
+
if (box) {
|
|
292
|
+
if (!boundingBox)
|
|
293
|
+
boundingBox = box;
|
|
294
|
+
else
|
|
295
|
+
boundingBox.union(box);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return boundingBox;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
this.vectorToScreenXY = point => {
|
|
302
|
+
point.project(this.camera);
|
|
303
|
+
let width = getDrawingWidth();
|
|
304
|
+
let height = getDrawingHeight();
|
|
305
|
+
let widthHalf = (width / 2);
|
|
306
|
+
let heightHalf = (height / 2);
|
|
307
|
+
point.x = (point.x * widthHalf) + widthHalf;
|
|
308
|
+
point.y = - (point.y * heightHalf) + heightHalf;
|
|
309
|
+
return point;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
this.getObjectsScreenXY = zincObjects => {
|
|
313
|
+
if (zincObjects && zincObjects.length > 0) {
|
|
314
|
+
let boundingBox = this.getBoundingBoxOfZincObjects(zincObjects);
|
|
315
|
+
const center = new THREE.Vector3();
|
|
316
|
+
boundingBox.getCenter(center);
|
|
317
|
+
return this.vectorToScreenXY(center);
|
|
318
|
+
}
|
|
319
|
+
return undefined;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
this.getNamedObjectsScreenXY = name => {
|
|
323
|
+
let zincObjects = this.findObjectsWithGroupName(name);
|
|
324
|
+
return this.getObjectsScreenXY(zincObjects);
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
this.addZincObject = zincObject => {
|
|
328
|
+
if (zincObject) {
|
|
329
|
+
rootRegion.addZincObject(zincObject);
|
|
330
|
+
if (zincCameraControls)
|
|
331
|
+
zincCameraControls.calculateMaxAllowedDistance(this);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Load a glyphset into this scene object.
|
|
337
|
+
*
|
|
338
|
+
* @param {String} metaurl - Provide informations such as transformations, colours
|
|
339
|
+
* and others for each of the glyph in the glyphsset.
|
|
340
|
+
* @param {String} glyphurl - regular json model file providing geometry of the glyph.
|
|
341
|
+
* @param {String} groupName - name to assign the glyphset's groupname to.
|
|
342
|
+
* @param {Function} finishCallback - Callback function which will be called
|
|
343
|
+
* once the glyphset is succssfully load in.
|
|
344
|
+
*/
|
|
345
|
+
this.loadGlyphsetURL = (metaurl, glyphurl, groupName, finishCallback) => {
|
|
346
|
+
sceneLoader.loadGlyphsetURL(rootRegion, metaurl, glyphurl, groupName, finishCallback);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Load a pointset into this scene object.
|
|
351
|
+
*
|
|
352
|
+
* @param {String} metaurl - Provide informations such as transformations, colours
|
|
353
|
+
* and others for each of the glyph in the glyphsset.
|
|
354
|
+
* @param {Boolean} timeEnabled - Indicate if morphing is enabled.
|
|
355
|
+
* @param {Boolean} morphColour - Indicate if color morphing is enabled.
|
|
356
|
+
* @param {STRING} groupName - name to assign the pointset's groupname to.
|
|
357
|
+
* @param {Function} finishCallback - Callback function which will be called
|
|
358
|
+
* once the glyphset is succssfully load in.
|
|
359
|
+
*/
|
|
360
|
+
this.loadPointsetURL = (url, timeEnabled, morphColour, groupName, finishCallback) => {
|
|
361
|
+
sceneLoader.loadPointsetURL(rootRegion, url, timeEnabled, morphColour, groupName, finishCallback);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Load lines into this scene object.
|
|
366
|
+
*
|
|
367
|
+
* @param {String} metaurl - Provide informations such as transformations, colours
|
|
368
|
+
* and others for each of the glyph in the glyphsset.
|
|
369
|
+
* @param {Boolean} timeEnabled - Indicate if morphing is enabled.
|
|
370
|
+
* @param {Boolean} morphColour - Indicate if color morphing is enabled.
|
|
371
|
+
* @param {STRING} groupName - name to assign the pointset's groupname to.
|
|
372
|
+
* @param {Function} finishCallback - Callback function which will be called
|
|
373
|
+
* once the glyphset is succssfully load in.
|
|
374
|
+
*/
|
|
375
|
+
this.loadLinesURL = (url, timeEnabled, morphColour, groupName, finishCallback) => {
|
|
376
|
+
sceneLoader.loadLinesURL(rootRegion, url, timeEnabled, morphColour, groupName, finishCallback);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Read a STL file into this scene, the geometry will be presented as
|
|
381
|
+
* {@link Zinc.Geometry}.
|
|
382
|
+
*
|
|
383
|
+
* @param {STRING} url - location to the STL file.
|
|
384
|
+
* @param {STRING} groupName - name to assign the geometry's groupname to.
|
|
385
|
+
* @param {Function} finishCallback - Callback function which will be called
|
|
386
|
+
* once the STL geometry is succssfully loaded.
|
|
387
|
+
*/
|
|
388
|
+
this.loadSTL = (url, groupName, finishCallback) => {
|
|
389
|
+
sceneLoader.loadSTL(rootRegion, url, groupName, finishCallback);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Read a OBJ file into this scene, the geometry will be presented as
|
|
394
|
+
* {@link Zinc.Geometry}.
|
|
395
|
+
*
|
|
396
|
+
* @param {STRING} url - location to the STL file.
|
|
397
|
+
* @param {STRING} groupName - name to assign the geometry's groupname to.
|
|
398
|
+
* @param {Function} finishCallback - Callback function which will be called
|
|
399
|
+
* once the OBJ geometry is succssfully loaded.
|
|
400
|
+
*/
|
|
401
|
+
this.loadOBJ = (url, groupName, finishCallback) => {
|
|
402
|
+
sceneLoader.loadOBJ(rootRegion, url, groupName, finishCallback);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Load a metadata file from the provided URL into this scene. Once
|
|
407
|
+
* succssful scene proceeds to read each items into scene for visualisations.
|
|
408
|
+
*
|
|
409
|
+
* @param {String} url - Location of the metafile
|
|
410
|
+
* @param {Function} finishCallback - Callback function which will be called
|
|
411
|
+
* for each glyphset and geometry that has been written in.
|
|
412
|
+
*/
|
|
413
|
+
this.loadMetadataURL = (url, finishCallback, allCompletedCallback) => {
|
|
414
|
+
sceneLoader.loadMetadataURL(rootRegion, url, finishCallback, allCompletedCallback);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Load a legacy model(s) format with the provided URLs and parameters. This only loads the geometry
|
|
419
|
+
* without any of the metadata. Therefore, extra parameters should be provided.
|
|
420
|
+
*
|
|
421
|
+
* @deprecated
|
|
422
|
+
*/
|
|
423
|
+
this.loadModelsURL = (urls, colours, opacities, timeEnabled, morphColour, finishCallback) => {
|
|
424
|
+
sceneLoader.loadModelsURL(rootRegion. urls, colours, opacities, timeEnabled, morphColour, finishCallback);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Load the viewport from an external location provided by the url.
|
|
429
|
+
* @param {String} URL - address to the file containing viewport information.
|
|
430
|
+
*/
|
|
431
|
+
this.loadViewURL = url => {
|
|
432
|
+
sceneLoader.loadViewURL(url);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Load a legacy file format containing the viewport and its meta file from an external
|
|
437
|
+
* location provided by the url. Use the new metadata format with
|
|
438
|
+
* {@link Zinc.Scene#loadMetadataURL} instead.
|
|
439
|
+
*
|
|
440
|
+
* @param {String} URL - address to the file containing viewport and model information.
|
|
441
|
+
* @deprecated
|
|
442
|
+
*/
|
|
443
|
+
this.loadFromViewURL = (jsonFilePrefix, finishCallback) => {
|
|
444
|
+
sceneLoader.loadFromViewURL(jsonFilePrefix, finishCallback);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Load GLTF into this scene object.
|
|
449
|
+
*/
|
|
450
|
+
this.loadGLTF = (url, finishCallback, options) => {
|
|
451
|
+
sceneLoader.loadGLTF(rootRegion, url, finishCallback, options);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
//Update the directional light for this scene.
|
|
455
|
+
this.updateDirectionalLight = () => {
|
|
456
|
+
zincCameraControls.updateDirectionalLight();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Add any {THREE.Object} into this scene.
|
|
461
|
+
* @param {THREE.Object} object - to be addded into this scene.
|
|
462
|
+
*/
|
|
463
|
+
this.addObject = object => {
|
|
464
|
+
scene.add(object);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Remove any {THREE.Object} from this scene.
|
|
469
|
+
* @param {THREE.Object} object - to be removed from this scene.
|
|
470
|
+
*/
|
|
471
|
+
this.removeObject = object => {
|
|
472
|
+
scene.remove(object);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Get the current time of the scene.
|
|
477
|
+
* @return {Number}
|
|
478
|
+
*/
|
|
479
|
+
this.getCurrentTime = () => {
|
|
480
|
+
if (videoHandler != undefined) {
|
|
481
|
+
return videoHandler.getCurrentTime(duration);
|
|
482
|
+
}
|
|
483
|
+
const time = rootRegion.getCurrentTime();
|
|
484
|
+
if (time !== -1)
|
|
485
|
+
return time;
|
|
486
|
+
|
|
487
|
+
return 0;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Set the current time of all the geometries and glyphsets of this scene.
|
|
492
|
+
* @param {Number} time - Value to set the time to.
|
|
493
|
+
*/
|
|
494
|
+
this.setMorphsTime = (time) => {
|
|
495
|
+
if (videoHandler != undefined) {
|
|
496
|
+
videoHandler.setMorphTime(time, duration);
|
|
497
|
+
}
|
|
498
|
+
rootRegion.setMorphTime(time, true);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Check if any object in this scene is time varying.
|
|
503
|
+
*
|
|
504
|
+
* @return {Boolean}
|
|
505
|
+
*/
|
|
506
|
+
this.isTimeVarying = () => {
|
|
507
|
+
if (videoHandler && videoHandler.video && !videoHandler.video.error) {
|
|
508
|
+
return true;
|
|
509
|
+
}
|
|
510
|
+
return rootRegion.isTimeVarying();
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* Update geometries and glyphsets based on the calculated time.
|
|
515
|
+
* @private
|
|
516
|
+
*/
|
|
517
|
+
this.renderGeometries = (playRate, delta, playAnimation) => {
|
|
518
|
+
// Let video dictates the progress if one is present
|
|
519
|
+
let options = {};
|
|
520
|
+
options.camera = zincCameraControls;
|
|
521
|
+
options.displayMarkers = this.displayMarkers;
|
|
522
|
+
options.markerDepths = [];
|
|
523
|
+
if (videoHandler) {
|
|
524
|
+
if (videoHandler.isReadyToPlay()) {
|
|
525
|
+
if (playAnimation) {
|
|
526
|
+
videoHandler.video.play();
|
|
527
|
+
} else {
|
|
528
|
+
videoHandler.video.pause();
|
|
529
|
+
}
|
|
530
|
+
const currentTime = videoHandler.video.currentTime /
|
|
531
|
+
videoHandler.getVideoDuration() * duration;
|
|
532
|
+
if (0 == sceneLoader.toBeDownloaded) {
|
|
533
|
+
zincCameraControls.setTime(currentTime);
|
|
534
|
+
zincCameraControls.update(0);
|
|
535
|
+
rootRegion.setMorphTime(currentTime, true);
|
|
536
|
+
rootRegion.renderGeometries(0, 0, playAnimation, undefined, true);
|
|
537
|
+
} else {
|
|
538
|
+
zincCameraControls.update(0);
|
|
539
|
+
}
|
|
540
|
+
//console.log(videoHandler.video.currentTime / videoHandler.getVideoDuration() * 6000);
|
|
541
|
+
} else {
|
|
542
|
+
myPlayRate = 0;
|
|
543
|
+
}
|
|
544
|
+
} else {
|
|
545
|
+
if (0 == sceneLoader.toBeDownloaded) {
|
|
546
|
+
zincCameraControls.update(delta);
|
|
547
|
+
rootRegion.renderGeometries(playRate, delta, playAnimation, options, true);
|
|
548
|
+
} else {
|
|
549
|
+
zincCameraControls.update(0);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Return the internal {THREE.Scene}.
|
|
556
|
+
* @return {THREE.Scene}
|
|
557
|
+
*/
|
|
558
|
+
this.getThreeJSScene = () => {
|
|
559
|
+
return scene;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
this.setVideoHandler = (videoHandlerIn) => {
|
|
563
|
+
if (!videoHandler)
|
|
564
|
+
videoHandler = videoHandlerIn;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Set a group of scenes into this parent scene. This group of
|
|
569
|
+
* scenes will also be rendered when this scene is rendered.
|
|
570
|
+
* @private
|
|
571
|
+
*/
|
|
572
|
+
this.setAdditionalScenesGroup = scenesGroup => {
|
|
573
|
+
scene.add(scenesGroup);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
let getWindowsPosition = (align, x_offset, y_offset, width, height,
|
|
577
|
+
renderer_width, renderer_height) => {
|
|
578
|
+
let x = 0;
|
|
579
|
+
let y = 0;
|
|
580
|
+
if (align.includes("top")) {
|
|
581
|
+
y = renderer_height - height - y_offset;
|
|
582
|
+
} else if (align.includes("bottom")) {
|
|
583
|
+
y = y_offset;
|
|
584
|
+
} else {
|
|
585
|
+
y = Math.floor((renderer_height - height) / 2.0);
|
|
586
|
+
}
|
|
587
|
+
if (align.includes("left")) {
|
|
588
|
+
x = x_offset;
|
|
589
|
+
} else if (align.includes("right")) {
|
|
590
|
+
x = renderer_width - x_offset- width;
|
|
591
|
+
} else {
|
|
592
|
+
x = Math.floor((renderer_width - width) / 2.0);
|
|
593
|
+
}
|
|
594
|
+
return {x: x, y: y};
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
const renderMinimap = renderer => {
|
|
598
|
+
if (this.displayMinimap === true) {
|
|
599
|
+
renderer.setScissorTest(true);
|
|
600
|
+
renderer.getSize(_markerTarget);
|
|
601
|
+
if (this.minimapScissor.updateRequired) {
|
|
602
|
+
scissor = getWindowsPosition(this.minimapScissor.align,
|
|
603
|
+
this.minimapScissor.x_offset,
|
|
604
|
+
this.minimapScissor.y_offset,
|
|
605
|
+
this.minimapScissor.width,
|
|
606
|
+
this.minimapScissor.height,
|
|
607
|
+
_markerTarget.x, _markerTarget.y);
|
|
608
|
+
this.minimapScissor.updateRequired = false;
|
|
609
|
+
}
|
|
610
|
+
renderer.setScissor(
|
|
611
|
+
scissor.x,
|
|
612
|
+
scissor.y,
|
|
613
|
+
this.minimapScissor.width,
|
|
614
|
+
this.minimapScissor.height);
|
|
615
|
+
renderer.setViewport(
|
|
616
|
+
scissor.x,
|
|
617
|
+
scissor.y,
|
|
618
|
+
this.minimapScissor.width,
|
|
619
|
+
this.minimapScissor.height);
|
|
620
|
+
minimap.updateCamera();
|
|
621
|
+
scene.add(minimap.mask);
|
|
622
|
+
renderer.render(scene, minimap.camera);
|
|
623
|
+
scene.remove(minimap.mask);
|
|
624
|
+
renderer.setScissorTest(false);
|
|
625
|
+
renderer.setViewport(0, 0, _markerTarget.x, _markerTarget.y);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* Render the scene.
|
|
631
|
+
* @private
|
|
632
|
+
*/
|
|
633
|
+
this.render = renderer => {
|
|
634
|
+
if (this.autoClearFlag)
|
|
635
|
+
renderer.clear();
|
|
636
|
+
if (stereoEffectFlag && stereoEffect) {
|
|
637
|
+
stereoEffect.render(scene, this.camera);
|
|
638
|
+
} else {
|
|
639
|
+
renderer.render(scene, this.camera);
|
|
640
|
+
renderMinimap(renderer);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Enable or disable interactive control, this is on by default.
|
|
646
|
+
*
|
|
647
|
+
* @param {Boolean} flag - Indicate either interactive control
|
|
648
|
+
* should be enabled or disabled.
|
|
649
|
+
*/
|
|
650
|
+
this.setInteractiveControlEnable = flag => {
|
|
651
|
+
if (flag == true)
|
|
652
|
+
zincCameraControls.enable();
|
|
653
|
+
else
|
|
654
|
+
zincCameraControls.disable();
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
/**
|
|
658
|
+
* Get the camera control of this scene.
|
|
659
|
+
* @return {Zinc.CameraControls}
|
|
660
|
+
*/
|
|
661
|
+
this.getZincCameraControls = () => {
|
|
662
|
+
return zincCameraControls;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Get the internal {THREE.Scene}.
|
|
667
|
+
* @return {THREE.Scene}
|
|
668
|
+
*/
|
|
669
|
+
this.getThreeJSScene = () => {
|
|
670
|
+
return scene;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Set the default duration value for geometries and glyphsets
|
|
675
|
+
* that are to be loaded into this scene.
|
|
676
|
+
* @param {Number} durationIn - duration of the scene.
|
|
677
|
+
*/
|
|
678
|
+
this.setDuration = durationIn => {
|
|
679
|
+
rootRegion.setDuration(durationIn);
|
|
680
|
+
duration = durationIn;
|
|
681
|
+
zincCameraControls.setPathDuration(durationIn);
|
|
682
|
+
sceneLoader.duration = durationIn;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
* Get the default duration value.
|
|
687
|
+
* returns {Number}
|
|
688
|
+
*/
|
|
689
|
+
this.getDuration = () => {
|
|
690
|
+
return duration;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* Enable or disable stereo effect of this scene.
|
|
695
|
+
* @param {Boolean} flag - Indicate either stereo effect control
|
|
696
|
+
* should be enabled or disabled.
|
|
697
|
+
*/
|
|
698
|
+
this.setStereoEffectEnable = stereoFlag => {
|
|
699
|
+
if (stereoFlag == true) {
|
|
700
|
+
if (!stereoEffect) {
|
|
701
|
+
stereoEffect = new require('./controls').StereoEffect(rendererIn);
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
rendererIn.setSize(getDrawingWidth(), getDrawingHeight());
|
|
705
|
+
this.camera.updateProjectionMatrix();
|
|
706
|
+
stereoEffectFlag = stereoFlag;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
this.objectIsInScene = zincObject => {
|
|
710
|
+
return rootRegion.objectIsInRegion(zincObject, true);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
this.alignBoundingBoxToCameraView = (boundingBox, transitionTime) => {
|
|
714
|
+
if (boundingBox) {
|
|
715
|
+
const center = new THREE.Vector3();
|
|
716
|
+
boundingBox.getCenter(center);
|
|
717
|
+
const viewport = this.getZincCameraControls().getCurrentViewport();
|
|
718
|
+
const target = new THREE.Vector3(viewport.targetPosition[0],
|
|
719
|
+
viewport.targetPosition[1], viewport.targetPosition[2]);
|
|
720
|
+
const eyePosition = new THREE.Vector3(viewport.eyePosition[0],
|
|
721
|
+
viewport.eyePosition[1], viewport.eyePosition[2]);
|
|
722
|
+
const upVector = new THREE.Vector3(viewport.upVector[0],
|
|
723
|
+
viewport.upVector[1], viewport.upVector[2]);
|
|
724
|
+
const newVec1 = new THREE.Vector3();
|
|
725
|
+
const newVec2 = new THREE.Vector3();
|
|
726
|
+
newVec1.subVectors(target, eyePosition).normalize();
|
|
727
|
+
newVec2.subVectors(target, center).normalize();
|
|
728
|
+
const newVec3 = new THREE.Vector3();
|
|
729
|
+
newVec3.crossVectors(newVec1, newVec2);
|
|
730
|
+
const angle = newVec1.angleTo(newVec2);
|
|
731
|
+
if (transitionTime > 0) {
|
|
732
|
+
this.getZincCameraControls().rotateCameraTransition(newVec3,
|
|
733
|
+
angle, transitionTime);
|
|
734
|
+
this.getZincCameraControls().enableCameraTransition();
|
|
735
|
+
} else {
|
|
736
|
+
this.getZincCameraControls().rotateAboutLookAtpoint(newVec3, angle);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
this.alignObjectToCameraView = (zincObject, transitionTime) => {
|
|
742
|
+
if (this.objectIsInScene(zincObject)) {
|
|
743
|
+
const boundingBox = zincObject.getBoundingBox();
|
|
744
|
+
this.alignBoundingBoxToCameraView(boundingBox, transitionTime);
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
this.setCameraTargetToObject = zincObject => {
|
|
749
|
+
if (this.objectIsInScene(zincObject)) {
|
|
750
|
+
const center = new THREE.Vector3();
|
|
751
|
+
const boundingBox = zincObject.getBoundingBox();
|
|
752
|
+
const viewport = this.getZincCameraControls().getCurrentViewport();
|
|
753
|
+
boundingBox.getCenter(center);
|
|
754
|
+
const target = new THREE.Vector3(viewport.targetPosition[0],
|
|
755
|
+
viewport.targetPosition[1], viewport.targetPosition[2]);
|
|
756
|
+
const eyePosition = new THREE.Vector3(viewport.eyePosition[0],
|
|
757
|
+
viewport.eyePosition[1], viewport.eyePosition[2]);
|
|
758
|
+
const newVec1 = new THREE.Vector3();
|
|
759
|
+
const newVec2 = new THREE.Vector3();
|
|
760
|
+
newVec1.subVectors(eyePosition, target);
|
|
761
|
+
newVec2.addVectors(center, newVec1);
|
|
762
|
+
viewport.eyePosition[0] = newVec2.x;
|
|
763
|
+
viewport.eyePosition[1] = newVec2.y;
|
|
764
|
+
viewport.eyePosition[2] = newVec2.z;
|
|
765
|
+
viewport.targetPosition[0] = center.x;
|
|
766
|
+
viewport.targetPosition[1] = center.y;
|
|
767
|
+
viewport.targetPosition[2] = center.z;
|
|
768
|
+
this.getZincCameraControls().setCurrentCameraSettings(viewport);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Check if stereo effect is enabled.
|
|
774
|
+
* @returns {Boolean}
|
|
775
|
+
*/
|
|
776
|
+
this.isStereoEffectEnable = () => {
|
|
777
|
+
return stereoEffectFlag;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Remove a ZincObject from this scene if it presents. This will eventually
|
|
782
|
+
* destroy the object and free up the memory.
|
|
783
|
+
* @param {Zinc.Object} zincObject - object to be removed from this scene.
|
|
784
|
+
*/
|
|
785
|
+
this.removeZincObject = zincObject => {
|
|
786
|
+
rootRegion.removeZincObject(zincObject);
|
|
787
|
+
if (zincCameraControls)
|
|
788
|
+
zincCameraControls.calculateMaxAllowedDistance(this);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Update pickable objects list
|
|
793
|
+
*/
|
|
794
|
+
this.updatePickableThreeJSObjects = () => {
|
|
795
|
+
pickableObjectsList.splice(0, pickableObjectsList.length);
|
|
796
|
+
rootRegion.getPickableThreeJSObjects(pickableObjectsList,
|
|
797
|
+
this.displayMarkers, true);
|
|
798
|
+
this.forcePickableObjectsUpdate = false;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Get all pickable objects.
|
|
803
|
+
*/
|
|
804
|
+
this.getPickableThreeJSObjects = () => {
|
|
805
|
+
//The list will only be updated if changes have been made
|
|
806
|
+
//in region or a flag has been raise
|
|
807
|
+
if (this.forcePickableObjectsUpdate ||
|
|
808
|
+
rootRegion.checkPickableUpdateRequred(true)) {
|
|
809
|
+
this.updatePickableThreeJSObjects();
|
|
810
|
+
}
|
|
811
|
+
return pickableObjectsList;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Get the Normalised coordinates on minimap if mouse event is
|
|
816
|
+
* inside the minimap
|
|
817
|
+
*/
|
|
818
|
+
this.getNormalisedMinimapCoordinates = (renderer, event) => {
|
|
819
|
+
if (this.displayMinimap) {
|
|
820
|
+
const target = new THREE.Vector2();
|
|
821
|
+
renderer.getSize(target);
|
|
822
|
+
let offsetY = target.y - event.clientY;
|
|
823
|
+
if (((scissor.x + this.minimapScissor.width) > event.clientX) &&
|
|
824
|
+
(event.clientX > scissor.x) &&
|
|
825
|
+
((scissor.y + this.minimapScissor.height) > offsetY) &&
|
|
826
|
+
(offsetY > scissor.y)) {
|
|
827
|
+
let x = ((event.clientX - scissor.x) /
|
|
828
|
+
this.minimapScissor.width) * 2.0 - 1.0;
|
|
829
|
+
let y = ((offsetY - scissor.y) /
|
|
830
|
+
this.minimapScissor.height) * 2.0 - 1.0;
|
|
831
|
+
return {"x": x, "y": y};
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return undefined;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Get the coordinates difference of the current viewing
|
|
839
|
+
* point and projected coordinates.
|
|
840
|
+
*/
|
|
841
|
+
this.getMinimapDiffFromNormalised = (x, y) => {
|
|
842
|
+
if (minimap)
|
|
843
|
+
return minimap.getDiffFromNormalised(x, y);
|
|
844
|
+
return undefined;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
this.isWebGL2 = () => {
|
|
848
|
+
return rendererIn.isWebGL2();
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Remove all objects that are created with ZincJS APIs and it will free the memory allocated.
|
|
853
|
+
* This does not remove obejcts that are added using the addObject APIs.
|
|
854
|
+
*/
|
|
855
|
+
this.clearAll = () => {
|
|
856
|
+
rootRegion.clear(true);
|
|
857
|
+
sceneLoader.toBeDwonloaded = 0;
|
|
858
|
+
if (zincCameraControls)
|
|
859
|
+
zincCameraControls.calculateMaxAllowedDistance(this);
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* All time stamp to the metadata TimeStamps field.
|
|
864
|
+
*/
|
|
865
|
+
this.addMetadataTimeStamp = (key, time) => {
|
|
866
|
+
metadata["TimeStamps"][key] = convertDurationObjectTomSec(time);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Get a specific metadata field.
|
|
871
|
+
*/
|
|
872
|
+
this.getMetadataTag = key => {
|
|
873
|
+
return metadata[key];
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/**
|
|
877
|
+
* Get all metadata set for the scene.
|
|
878
|
+
*/
|
|
879
|
+
this.getMetadata = () => {
|
|
880
|
+
return metadata;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
/**
|
|
884
|
+
* Set a specific metadata field.
|
|
885
|
+
*/
|
|
886
|
+
this.setMetadataTag = (key, value) => {
|
|
887
|
+
metadata[key] = value;
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* Remove a specific metadata field.
|
|
892
|
+
*/
|
|
893
|
+
this.removeMetadataTag = key => {
|
|
894
|
+
delete metadata[key];
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Reset all metadata fields to original value.
|
|
899
|
+
*/
|
|
900
|
+
this.resetMetadata = () => {
|
|
901
|
+
metadata = defaultMetadata();
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
/**
|
|
905
|
+
* Reset duration of scene to default value.
|
|
906
|
+
*/
|
|
907
|
+
this.resetDuration = () => {
|
|
908
|
+
this.setDuration(defaultDuration);
|
|
909
|
+
}
|
|
910
|
+
|
|
911
|
+
// Turn the object into a readable string {years: years,months: months,
|
|
912
|
+
// weeks: weeks, days: days, hours: hours, mins: mins, secs: secs }
|
|
913
|
+
const convertDurationObjectToString = duration => {
|
|
914
|
+
return [
|
|
915
|
+
...(duration.years ? [`${duration.years}years`] : []),
|
|
916
|
+
...(duration.months ? [`${duration.months}months`] : []),
|
|
917
|
+
...(duration.weeks ? [`${duration.weeks}weeks`] : []),
|
|
918
|
+
...(duration.days ? [`${duration.days}days`] : []),
|
|
919
|
+
...(duration.hours ? [`${duration.hours}hours`] : []),
|
|
920
|
+
...(duration.mins ? [`${duration.mins}mins`] : []),
|
|
921
|
+
...(duration.secs ? [`${duration.secs}secs`] : []),
|
|
922
|
+
].join(' ');
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// Turn the object into a number representing milliesecond {years: years,months: months,
|
|
926
|
+
// weeks: weeks, days: days, hours: hours, mins: mins, secs: secs }
|
|
927
|
+
const convertDurationObjectTomSec = duration => {
|
|
928
|
+
return duration.years ? duration.years * 31536000000 : 0 +
|
|
929
|
+
duration.months ? duration.months * 2592000000 : 0 +
|
|
930
|
+
duration.weeks ? duration.weeks * 604800000 : 0 +
|
|
931
|
+
duration.days ? duration.days * 86400000 : 0 +
|
|
932
|
+
duration.hours ? duration.hours * 3600000 : 0 +
|
|
933
|
+
duration.mins ? duration.mins * 60000 : 0 +
|
|
934
|
+
duration.secs ? duration.secs * 1000 : 0;
|
|
935
|
+
}
|
|
936
|
+
|
|
937
|
+
// Set the readable duration and timer using an object
|
|
938
|
+
// with the following format {years: years,months: months, weeks: weeks, days: days,
|
|
939
|
+
// hours: hours, mins: mins, secs: secs }
|
|
940
|
+
this.setDurationFromObject = duration => {
|
|
941
|
+
const string = convertDurationObjectToString(duration);
|
|
942
|
+
const millisec = convertDurationObjectTomSec(duration);
|
|
943
|
+
this.setMetadataTag("Duration", string);
|
|
944
|
+
this.setDuration(millisec);
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
// Set the readable original duration using an object
|
|
948
|
+
// with the following format {years: years,months: months, weeks: weeks, days: days,
|
|
949
|
+
// hours: hours, mins: mins, secs: secs }
|
|
950
|
+
this.setOriginalDurationFromObject = duration => {
|
|
951
|
+
const string = convertDurationObjectToString(duration);
|
|
952
|
+
this.setMetadataTag("OriginalDuration", string);
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
this.exportGLTF = (binary) => {
|
|
956
|
+
const exporter = new SceneExporter(this);
|
|
957
|
+
return exporter.exportGLTF(binary);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
this.getRootRegion = () => {
|
|
961
|
+
return rootRegion;
|
|
962
|
+
}
|
|
963
|
+
}
|