@xeokit/xeokit-sdk 2.6.28 → 2.6.29

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 (40) hide show
  1. package/README.md +1 -0
  2. package/dist/xeokit-sdk.cjs.js +915 -220
  3. package/dist/xeokit-sdk.es.js +910 -221
  4. package/dist/xeokit-sdk.es5.js +576 -486
  5. package/dist/xeokit-sdk.min.cjs.js +5 -5
  6. package/dist/xeokit-sdk.min.es.js +5 -5
  7. package/dist/xeokit-sdk.min.es5.js +4 -4
  8. package/package.json +1 -1
  9. package/src/extras/PointerCircle/PointerCircle.js +1 -1
  10. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +22 -41
  11. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +3 -18
  12. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +20 -41
  13. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +4 -20
  14. package/src/plugins/DistanceMeasurementsPlugin/index.js +1 -1
  15. package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +31 -1
  16. package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +20 -8
  17. package/src/plugins/ZonesPlugin/ZonesPlugin.js +1939 -0
  18. package/src/plugins/ZonesPlugin/index.js +1 -1875
  19. package/src/viewer/Viewer.js +2 -2
  20. package/src/viewer/scene/math/MeshSurfaceArea.js +90 -0
  21. package/src/viewer/scene/math/MeshVolume.js +102 -0
  22. package/src/viewer/scene/math/index.js +3 -0
  23. package/src/viewer/scene/math/isTriangleMeshSolid.js +162 -0
  24. package/src/viewer/scene/math/math.js +8 -0
  25. package/src/viewer/scene/model/SceneModel.js +64 -34
  26. package/src/viewer/scene/model/SceneModelEntity.js +46 -1
  27. package/src/viewer/scene/model/SceneModelMesh.js +74 -1
  28. package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +7 -1
  29. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +77 -1
  30. package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +6 -1
  31. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +6 -1
  32. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +33 -12
  33. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +6 -1
  34. package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +6 -1
  35. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +31 -10
  36. package/src/viewer/scene/scene/Scene.js +16 -5
  37. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +0 -1
  38. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +7 -0
  39. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.d.ts +26 -1
  40. package/types/plugins/DistanceMeasurementsPlugin/index.d.ts +3 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.6.28",
3
+ "version": "2.6.29",
4
4
  "description": "Web Programming Toolkit for 3D/2D BIM and AEC Graphics",
5
5
  "module": "./dist/xeokit-sdk.es.js",
6
6
  "main": "./dist/xeokit-sdk.cjs.js",
@@ -128,7 +128,7 @@ export class PointerCircle {
128
128
  destroy() {
129
129
  if (!this._destroyed) {
130
130
  this.stop();
131
- document.body.removeChild(this._circleDiv);
131
+ this._circleDiv.parentElement.removeChild(this._circleDiv);
132
132
  this._destroyed = true;
133
133
  }
134
134
  }
@@ -61,22 +61,13 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
61
61
  this.pointerLens = cfg.pointerLens;
62
62
 
63
63
  this._active = false;
64
- this._mouseState = MOUSE_FINDING_ORIGIN;
65
64
 
66
65
  this._currentAngleMeasurement = null;
67
66
 
68
- // init markerDiv element (think about making its style configurable)
69
67
  this._initMarkerDiv()
70
68
 
71
- this._onMouseHoverSurface = null;
72
- this._onHoverNothing = null;
73
- this._onPickedNothing = null;
74
- this._onPickedSurface = null;
75
-
76
- this._onInputMouseDown = null;
77
- this._onInputMouseUp = null;
78
-
79
69
  this._snapping = cfg.snapping !== false;
70
+ this._mouseState = MOUSE_FINDING_ORIGIN;
80
71
 
81
72
  this._attachPlugin(angleMeasurementsPlugin, cfg);
82
73
  }
@@ -141,20 +132,10 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
141
132
  *
142
133
  * This is `true` by default.
143
134
  *
144
- * Internally, this deactivates then activates the AngleMeasurementsMouseControl when changed, which means that
145
- * it will destroy any AngleMeasurements currently under construction, and incurs some overhead, since it unbinds
146
- * and rebinds various input handlers.
147
- *
148
135
  * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsMouseControl.
149
136
  */
150
137
  set snapping(snapping) {
151
- if (snapping !== this._snapping) {
152
- this._snapping = snapping;
153
- this.deactivate();
154
- this.activate();
155
- } else {
156
- this._snapping = snapping;
157
- }
138
+ this._snapping = snapping;
158
139
  }
159
140
 
160
141
  /**
@@ -198,11 +179,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
198
179
 
199
180
  const pagePos = math.vec2();
200
181
 
201
- this._onMouseHoverSurface = cameraControl.on(
202
- this._snapping
203
- ? "hoverSnapOrSurface"
204
- : "hoverSurface",
205
- event => {
182
+ const hoverOn = event => {
206
183
  if (event.snappedToVertex || event.snappedToEdge) {
207
184
  if (pointerLens) {
208
185
  pointerLens.visible = true;
@@ -264,7 +241,10 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
264
241
  canvas.style.cursor = "pointer";
265
242
  break;
266
243
  }
267
- });
244
+ };
245
+ this._onHoverSnapOrSurface = cameraControl.on("hoverSnapOrSurface", e => { if (this._snapping) hoverOn(e); });
246
+ this._onHoverSurface = cameraControl.on("hoverSurface", e => { if (! this._snapping) hoverOn(e); });
247
+
268
248
  canvas.addEventListener('mousedown', this._onMouseDown = (e) => {
269
249
  if (e.which !== 1) {
270
250
  return;
@@ -352,11 +332,8 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
352
332
  break;
353
333
  }
354
334
  });
355
- this._onMouseHoverOff = cameraControl.on(
356
- this._snapping
357
- ? "hoverSnapOrSurfaceOff"
358
- : "hoverOff",
359
- event => {
335
+
336
+ const hoverOff = event => {
360
337
  mouseHovering = false;
361
338
  if (pointerLens) {
362
339
  pointerLens.visible = true;
@@ -386,7 +363,10 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
386
363
  }
387
364
  canvas.style.cursor = "default";
388
365
  }
389
- });
366
+ };
367
+ this._onHoverSnapOrSurfaceOff = cameraControl.on("hoverSnapOrSurfaceOff", e => { if (this._snapping) hoverOff(e); });
368
+ this._onHoverOff = cameraControl.on("hoverOff", e => { if (! this._snapping) hoverOff(e); });
369
+
390
370
  this._active = true;
391
371
  }
392
372
 
@@ -399,22 +379,22 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
399
379
  if (!this._active) {
400
380
  return;
401
381
  }
382
+
402
383
  if (this.pointerLens) {
403
384
  this.pointerLens.visible = false;
404
385
  }
405
- if (this.markerDiv) {
406
- this._destroyMarkerDiv()
407
- }
386
+
408
387
  this.reset();
388
+
409
389
  const canvas = this.scene.canvas.canvas;
410
390
  canvas.removeEventListener("mousedown", this._onMouseDown);
411
391
  canvas.removeEventListener("mouseup", this._onMouseUp);
412
392
  const cameraControl = this.angleMeasurementsPlugin.viewer.cameraControl;
413
- cameraControl.off(this._onMouseHoverSurface);
414
- cameraControl.off(this._onPickedSurface);
415
- cameraControl.off(this._onHoverNothing);
416
- cameraControl.off(this._onPickedNothing);
417
- this._currentAngleMeasurement = null;
393
+ cameraControl.off(this._onHoverSnapOrSurface);
394
+ cameraControl.off(this._onHoverSurface);
395
+ cameraControl.off(this._onHoverSnapOrSurfaceOff);
396
+ cameraControl.off(this._onHoverOff);
397
+
418
398
  this._active = false;
419
399
  }
420
400
 
@@ -437,6 +417,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
437
417
  this._currentAngleMeasurement.destroy();
438
418
  this._currentAngleMeasurement = null;
439
419
  }
420
+
440
421
  this._mouseState = MOUSE_FINDING_ORIGIN;
441
422
  }
442
423
 
@@ -55,8 +55,6 @@ export class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
55
55
 
56
56
  this._currentAngleMeasurement = null;
57
57
 
58
- this._onCanvasTouchStart = null;
59
- this._onCanvasTouchEnd = null;
60
58
  this._longTouchTimeoutMs = 300;
61
59
  this._snapping = cfg.snapping !== false;
62
60
  this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;
@@ -92,20 +90,10 @@ export class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
92
90
  *
93
91
  * This is `true` by default.
94
92
  *
95
- * Internally, this deactivates then activates the AngleMeasurementsMouseControl when changed, which means that
96
- * it will destroy any AngleMeasurements currently under construction, and incurs some overhead, since it unbinds
97
- * and rebinds various input handlers.
98
- *
99
93
  * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this AngleMeasurementsMouseControl.
100
94
  */
101
95
  set snapping(snapping) {
102
- if (snapping !== this._snapping) {
103
- this._snapping = snapping;
104
- this.deactivate();
105
- this.activate();
106
- } else {
107
- this._snapping = snapping;
108
- }
96
+ this._snapping = snapping;
109
97
  }
110
98
 
111
99
  /**
@@ -878,14 +866,11 @@ export class AngleMeasurementsTouchControl extends AngleMeasurementsControl {
878
866
  this.plugin.pointerLens.visible = false;
879
867
  }
880
868
  this.reset();
869
+
881
870
  const canvas = this.plugin.viewer.scene.canvas.canvas;
882
871
  canvas.removeEventListener("touchstart", this._onCanvasTouchStart);
883
872
  canvas.removeEventListener("touchend", this._onCanvasTouchEnd);
884
- if (this._currentAngleMeasurement) {
885
- this.angleMeasurementsPlugin.fire("measurementCancel", this._currentAngleMeasurement);
886
- this._currentAngleMeasurement.destroy();
887
- this._currentAngleMeasurement = null;
888
- }
873
+
889
874
  this._active = false;
890
875
  this.plugin.viewer.cameraControl.active = true;
891
876
  }
@@ -74,12 +74,6 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
74
74
 
75
75
  this._initMarkerDiv()
76
76
 
77
- this._onCameraControlHoverSnapOrSurface = null;
78
- this._onCameraControlHoverSnapOrSurfaceOff = null;
79
- this._onMouseDown = null;
80
- this._onMouseUp = null;
81
- this._onCanvasTouchStart = null;
82
- this._onCanvasTouchEnd = null;
83
77
  this._snapping = cfg.snapping !== false;
84
78
  this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;
85
79
 
@@ -143,20 +137,10 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
143
137
  *
144
138
  * This is `true` by default.
145
139
  *
146
- * Internally, this deactivates then activates the DistanceMeasurementsMouseControl when changed, which means that
147
- * it will destroy any DistanceMeasurements currently under construction, and incurs some overhead, since it unbinds
148
- * and rebinds various input handlers.
149
- *
150
140
  * @param snapping
151
141
  */
152
142
  set snapping(snapping) {
153
- if (snapping !== this._snapping) {
154
- this._snapping = snapping;
155
- this.deactivate();
156
- this.activate();
157
- } else {
158
- this._snapping = snapping;
159
- }
143
+ this._snapping = snapping;
160
144
  }
161
145
 
162
146
  /**
@@ -168,7 +152,7 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
168
152
  get snapping() {
169
153
  return this._snapping;
170
154
  }
171
-
155
+
172
156
  /**
173
157
  * Activates this DistanceMeasurementsMouseControl, ready to respond to input.
174
158
  */
@@ -203,11 +187,8 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
203
187
  const getLeft = el => el.offsetLeft + (el.offsetParent && (el.offsetParent !== canvas.parentNode) && getLeft(el.offsetParent));
204
188
 
205
189
  const pagePos = math.vec2();
206
-
207
- this._onCameraControlHoverSnapOrSurface = cameraControl.on(
208
- this._snapping
209
- ? "hoverSnapOrSurface"
210
- : "hoverSurface", event => {
190
+
191
+ const hoverOn = event => {
211
192
  const canvasPos = event.snappedCanvasPos || event.canvasPos;
212
193
  mouseHovering = true;
213
194
  pointerWorldPos.set(event.worldPos);
@@ -260,7 +241,9 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
260
241
  this._markerDiv.style.left = `-10000px`;
261
242
  this._markerDiv.style.top = `-10000px`;
262
243
  }
263
- });
244
+ };
245
+ this._onHoverSnapOrSurface = cameraControl.on("hoverSnapOrSurface", e => { if (this._snapping) hoverOn(e); });
246
+ this._onHoverSurface = cameraControl.on("hoverSurface", e => { if (! this._snapping) hoverOn(e); });
264
247
 
265
248
  canvas.addEventListener('mousedown', this._onMouseDown = (e) => {
266
249
  if (e.which !== 1) {
@@ -321,10 +304,7 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
321
304
  }
322
305
  });
323
306
 
324
- this._onCameraControlHoverSnapOrSurfaceOff = cameraControl.on(
325
- this._snapping
326
- ? "hoverSnapOrSurfaceOff"
327
- : "hoverOff", event => {
307
+ const hoverOff = event => {
328
308
  if (this.pointerLens) {
329
309
  this.pointerLens.visible = true;
330
310
  this.pointerLens.canvasPos = event.canvasPos;
@@ -339,7 +319,9 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
339
319
  this._currentDistanceMeasurement.axisVisible = false;
340
320
  }
341
321
  canvas.style.cursor = "default";
342
- });
322
+ };
323
+ this._onHoverSnapOrSurfaceOff = cameraControl.on("hoverSnapOrSurfaceOff", e => { if (this._snapping) hoverOff(e); });
324
+ this._onHoverOff = cameraControl.on("hoverOff", e => { if (! this._snapping) hoverOff(e); });
343
325
 
344
326
  this._active = true;
345
327
  }
@@ -353,27 +335,24 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
353
335
  if (!this._active) {
354
336
  return;
355
337
  }
356
-
338
+
357
339
  this.fire("activated", false);
358
340
 
359
341
  if (this.pointerLens) {
360
342
  this.pointerLens.visible = false;
361
343
  }
362
- // if (this._markerDiv) {
363
- // this._destroyMarkerDiv()
364
- // }
365
- // this.reset();
344
+
345
+ this.reset();
346
+
366
347
  const canvas = this.scene.canvas.canvas;
367
348
  canvas.removeEventListener("mousedown", this._onMouseDown);
368
349
  canvas.removeEventListener("mouseup", this._onMouseUp);
369
350
  const cameraControl = this.distanceMeasurementsPlugin.viewer.cameraControl;
370
- cameraControl.off(this._onCameraControlHoverSnapOrSurface);
371
- cameraControl.off(this._onCameraControlHoverSnapOrSurfaceOff);
372
- // if (this._currentDistanceMeasurement) {
373
- // this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
374
- // this._currentDistanceMeasurement.destroy();
375
- // this._currentDistanceMeasurement = null;
376
- // }
351
+ cameraControl.off(this._onHoverSnapOrSurface);
352
+ cameraControl.off(this._onHoverSurface);
353
+ cameraControl.off(this._onHoverSnapOrSurfaceOff);
354
+ cameraControl.off(this._onHoverOff);
355
+
377
356
  this._active = false;
378
357
  }
379
358
 
@@ -60,11 +60,8 @@ export class DistanceMeasurementsTouchControl extends DistanceMeasurementsContro
60
60
  targetVisible: null,
61
61
  }
62
62
 
63
- this._onCanvasTouchStart = null;
64
- this._onCanvasTouchEnd = null;
65
63
  this._longTouchTimeoutMs = 300;
66
64
  this._snapping = cfg.snapping !== false;
67
- this._touchState = WAITING_FOR_ORIGIN_TOUCH_START;
68
65
 
69
66
  this._attachPlugin(distanceMeasurementsPlugin, cfg);
70
67
  }
@@ -97,20 +94,10 @@ export class DistanceMeasurementsTouchControl extends DistanceMeasurementsContro
97
94
  *
98
95
  * This is `true` by default.
99
96
  *
100
- * Internally, this deactivates then activates the DistanceMeasurementsTouchControl when changed, which means that
101
- * it will destroy any DistanceMeasurements currently under construction, and incurs some overhead, since it unbinds
102
- * and rebinds various input handlers.
103
- *
104
97
  * @param {boolean} snapping Whether to enable snap-to-vertex and snap-edge for this DistanceMeasurementsTouchControl.
105
98
  */
106
99
  set snapping(snapping) {
107
- if (snapping !== this._snapping) {
108
- this._snapping = snapping;
109
- this.deactivate();
110
- this.activate();
111
- } else {
112
- this._snapping = snapping;
113
- }
100
+ this._snapping = snapping;
114
101
  }
115
102
 
116
103
  /**
@@ -725,14 +712,11 @@ export class DistanceMeasurementsTouchControl extends DistanceMeasurementsContro
725
712
  this.plugin.pointerLens.visible = false;
726
713
  }
727
714
  this.reset();
715
+
728
716
  const canvas = this.plugin.viewer.scene.canvas.canvas;
729
717
  canvas.removeEventListener("touchstart", this._onCanvasTouchStart);
730
718
  canvas.removeEventListener("touchend", this._onCanvasTouchEnd);
731
- if (this._currentDistanceMeasurement) {
732
- this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
733
- this._currentDistanceMeasurement.destroy();
734
- this._currentDistanceMeasurement = null;
735
- }
719
+
736
720
  this._active = false;
737
721
  this.plugin.viewer.cameraControl.active = true;
738
722
  }
@@ -748,12 +732,12 @@ export class DistanceMeasurementsTouchControl extends DistanceMeasurementsContro
748
732
  if (!this._active) {
749
733
  return;
750
734
  }
735
+
751
736
  if (this._currentDistanceMeasurement) {
752
737
  this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
753
738
  this._currentDistanceMeasurement.destroy();
754
739
  this._currentDistanceMeasurement = null;
755
740
  }
756
- this._mouseState = WAITING_FOR_ORIGIN_TOUCH_START;
757
741
  }
758
742
 
759
743
  /**
@@ -7,7 +7,7 @@ import {Component} from "../../viewer/scene/Component.js";
7
7
  import {math} from "../../viewer/scene/math/math.js";
8
8
  import {activateDraggableDots} from "../../../src/plugins/lib/ui/index.js";
9
9
 
10
- class DistanceMeasurementEditControl extends Component {
10
+ export class DistanceMeasurementEditControl extends Component {
11
11
 
12
12
  /**
13
13
  * Edits {@link DistanceMeasurement} with mouse and/or touch input.
@@ -675,13 +675,43 @@ class StoreyViewsPlugin extends Plugin {
675
675
  getStoreyContainingWorldPos(worldPos) {
676
676
  for (var storeyId in this.storeys) {
677
677
  const storey = this.storeys[storeyId];
678
- if (math.point3AABB3Intersect(storey.storeyAABB, worldPos)) {
678
+ if (math.point3AABB3AbsoluteIntersect(storey.storeyAABB, worldPos)) {
679
679
  return storeyId;
680
680
  }
681
681
  }
682
682
  return null;
683
683
  }
684
684
 
685
+ /**
686
+ * Gets the ID of the storey which's bounding box contains the y point of the world position
687
+ *
688
+ * @param {Number[]} worldPos 3D World-space position.
689
+ * @returns {String} ID of the storey containing the position, or null if the position falls outside all the storeys.
690
+ */
691
+ getStoreyInVerticalRange(worldPos) {
692
+ for(let storeyId in this.storeys) {
693
+ const storey = this.storeys[storeyId];
694
+ const aabb = [0,0,0,0,0,0], pos = [0,0,0];
695
+ aabb[1] = storey.storeyAABB[1];
696
+ aabb[4] = storey.storeyAABB[4];
697
+ pos[1] = worldPos[1];
698
+ if (math.point3AABB3AbsoluteIntersect(aabb, pos)) {
699
+ return storeyId;
700
+ }
701
+ }
702
+ return null;
703
+ }
704
+
705
+ isPositionAboveOrBelowBuilding(worldPos){
706
+ const keys = Object.keys(this.storeys);
707
+ const ids = [keys[0], keys[keys.length-1]];
708
+ if(worldPos[1] < this.storeys[ids[0]].storeyAABB[1])
709
+ return ids[0];
710
+ else if (worldPos[1] > this.storeys[ids[1]].storeyAABB[4])
711
+ return ids[1];
712
+ return null;
713
+ }
714
+
685
715
  /**
686
716
  * Converts a 3D World-space position to a 2D position within a StoreyMap image.
687
717
  *
@@ -942,6 +942,9 @@ class XKTLoaderPlugin extends Plugin {
942
942
  this.viewer.scene.canvas.spinner.processes++;
943
943
 
944
944
  const finish = () => {
945
+ if (sceneModel.destroyed) {
946
+ return;
947
+ }
945
948
  // this._createDefaultMetaModelIfNeeded(sceneModel, params, options);
946
949
  sceneModel.finalize();
947
950
  metaModel.finalize();
@@ -1023,7 +1026,9 @@ class XKTLoaderPlugin extends Plugin {
1023
1026
  const loadJSONs = (metaDataFiles, done, error) => {
1024
1027
  let i = 0;
1025
1028
  const loadNext = () => {
1026
- if (i >= metaDataFiles.length) {
1029
+ if (sceneModel.destroyed) {
1030
+ done();
1031
+ } else if (i >= metaDataFiles.length) {
1027
1032
  done();
1028
1033
  } else {
1029
1034
  this._dataSource.getMetaModel(`${baseDir}${metaDataFiles[i]}`, (metaModelData) => {
@@ -1033,7 +1038,7 @@ class XKTLoaderPlugin extends Plugin {
1033
1038
  globalizeObjectIds: options.globalizeObjectIds
1034
1039
  });
1035
1040
  i++;
1036
- this.scheduleTask(loadNext, 100);
1041
+ this.scheduleTask(loadNext, 200);
1037
1042
  }, error);
1038
1043
  }
1039
1044
  }
@@ -1042,13 +1047,16 @@ class XKTLoaderPlugin extends Plugin {
1042
1047
  const loadXKTs_excludeTheirMetaModels = (xktFiles, done, error) => { // Load XKTs, ignore metamodels in the XKT
1043
1048
  let i = 0;
1044
1049
  const loadNext = () => {
1045
- if (i >= xktFiles.length) {
1050
+ if (sceneModel.destroyed) {
1051
+ done();
1052
+ } else if (i >= xktFiles.length) {
1046
1053
  done();
1047
1054
  } else {
1048
1055
  this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {
1049
1056
  this._parseModel(arrayBuffer, params, options, sceneModel, null /* Ignore metamodel in XKT */, manifestCtx);
1057
+ sceneModel.preFinalize();
1050
1058
  i++;
1051
- this.scheduleTask(loadNext, 100);
1059
+ this.scheduleTask(loadNext, 200);
1052
1060
  }, error);
1053
1061
  }
1054
1062
  }
@@ -1057,13 +1065,16 @@ class XKTLoaderPlugin extends Plugin {
1057
1065
  const loadXKTs_includeTheirMetaModels = (xktFiles, done, error) => { // Load XKTs, parse metamodels from the XKT
1058
1066
  let i = 0;
1059
1067
  const loadNext = () => {
1060
- if (i >= xktFiles.length) {
1068
+ if (sceneModel.destroyed) {
1069
+ done();
1070
+ } else if (i >= xktFiles.length) {
1061
1071
  done();
1062
1072
  } else {
1063
1073
  this._dataSource.getXKT(`${baseDir}${xktFiles[i]}`, (arrayBuffer) => {
1064
1074
  this._parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx);
1075
+ sceneModel.preFinalize();
1065
1076
  i++;
1066
- this.scheduleTask(loadNext, 100);
1077
+ this.scheduleTask(loadNext, 200);
1067
1078
  }, error);
1068
1079
  }
1069
1080
  }
@@ -1113,11 +1124,12 @@ class XKTLoaderPlugin extends Plugin {
1113
1124
  _loadModel(src, params, options, sceneModel, metaModel, manifestCtx, done, error) {
1114
1125
  this._dataSource.getXKT(params.src, (arrayBuffer) => {
1115
1126
  this._parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx);
1127
+ sceneModel.preFinalize();
1116
1128
  done();
1117
1129
  }, error);
1118
1130
  }
1119
1131
 
1120
- _parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx) {
1132
+ async _parseModel(arrayBuffer, params, options, sceneModel, metaModel, manifestCtx) {
1121
1133
  if (sceneModel.destroyed) {
1122
1134
  return;
1123
1135
  }
@@ -1129,7 +1141,7 @@ class XKTLoaderPlugin extends Plugin {
1129
1141
  this.error("Unsupported .XKT file version: " + xktVersion + " - this XKTLoaderPlugin supports versions " + Object.keys(parsers));
1130
1142
  return;
1131
1143
  }
1132
- this.log("Loading .xkt V" + xktVersion);
1144
+ // this.log("Loading .xkt V" + xktVersion);
1133
1145
  const numElements = dataView.getUint32(4, true);
1134
1146
  const elements = [];
1135
1147
  let byteOffset = (numElements + 2) * 4;