@xeokit/xeokit-sdk 2.0.14 → 2.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.
@@ -8261,6 +8261,20 @@ class PerformanceNode {
8261
8261
  return this._numTriangles;
8262
8262
  }
8263
8263
 
8264
+ /**
8265
+ * Gets if this PerformanceNode is visible.
8266
+ *
8267
+ * Only rendered when {@link PerformanceNode#visible} is ````true```` and {@link PerformanceNode#culled} is ````false````.
8268
+ *
8269
+ * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#visible} are ````true```` the PerformanceNode will be
8270
+ * registered by {@link PerformanceNode#id} in {@link Scene#visibleObjects}.
8271
+ *
8272
+ * @type {Boolean}
8273
+ */
8274
+ get visible() {
8275
+ return this._getFlag(ENTITY_FLAGS.VISIBLE);
8276
+ }
8277
+
8264
8278
  /**
8265
8279
  * Sets if this PerformanceNode is visible.
8266
8280
  *
@@ -8290,21 +8304,15 @@ class PerformanceNode {
8290
8304
  }
8291
8305
 
8292
8306
  /**
8293
- * Gets if this PerformanceNode is visible.
8294
- *
8295
- * Only rendered when {@link PerformanceNode#visible} is ````true```` and {@link PerformanceNode#culled} is ````false````.
8307
+ * Gets if this PerformanceNode is highlighted.
8296
8308
  *
8297
- * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#visible} are ````true```` the PerformanceNode will be
8298
- * registered by {@link PerformanceNode#id} in {@link Scene#visibleObjects}.
8309
+ * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#highlighted} are ````true```` the PerformanceNode will be
8310
+ * registered by {@link PerformanceNode#id} in {@link Scene#highlightedObjects}.
8299
8311
  *
8300
8312
  * @type {Boolean}
8301
8313
  */
8302
- get visible() {
8303
- return this._getFlag(ENTITY_FLAGS.VISIBLE);
8304
- }
8305
-
8306
- _getFlag(flag) {
8307
- return !!(this._flags & flag);
8314
+ get highlighted() {
8315
+ return this._getFlag(ENTITY_FLAGS.HIGHLIGHTED);
8308
8316
  }
8309
8317
 
8310
8318
  /**
@@ -8334,15 +8342,15 @@ class PerformanceNode {
8334
8342
  }
8335
8343
 
8336
8344
  /**
8337
- * Gets if this PerformanceNode is highlighted.
8345
+ * Gets if this PerformanceNode is xrayed.
8338
8346
  *
8339
- * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#highlighted} are ````true```` the PerformanceNode will be
8340
- * registered by {@link PerformanceNode#id} in {@link Scene#highlightedObjects}.
8347
+ * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#xrayed} are ````true```` the PerformanceNode will be
8348
+ * registered by {@link PerformanceNode#id} in {@link Scene#xrayedObjects}.
8341
8349
  *
8342
8350
  * @type {Boolean}
8343
8351
  */
8344
- get highlighted() {
8345
- return this._getFlag(ENTITY_FLAGS.HIGHLIGHTED);
8352
+ get xrayed() {
8353
+ return this._getFlag(ENTITY_FLAGS.XRAYED);
8346
8354
  }
8347
8355
 
8348
8356
  /**
@@ -8372,15 +8380,15 @@ class PerformanceNode {
8372
8380
  }
8373
8381
 
8374
8382
  /**
8375
- * Gets if this PerformanceNode is xrayed.
8383
+ * Sets if this PerformanceNode is selected.
8376
8384
  *
8377
- * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#xrayed} are ````true```` the PerformanceNode will be
8378
- * registered by {@link PerformanceNode#id} in {@link Scene#xrayedObjects}.
8385
+ * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#selected} are ````true```` the PerformanceNode will be
8386
+ * registered by {@link PerformanceNode#id} in {@link Scene#selectedObjects}.
8379
8387
  *
8380
8388
  * @type {Boolean}
8381
8389
  */
8382
- get xrayed() {
8383
- return this._getFlag(ENTITY_FLAGS.XRAYED);
8390
+ get selected() {
8391
+ return this._getFlag(ENTITY_FLAGS.SELECTED);
8384
8392
  }
8385
8393
 
8386
8394
  /**
@@ -8410,15 +8418,12 @@ class PerformanceNode {
8410
8418
  }
8411
8419
 
8412
8420
  /**
8413
- * Sets if this PerformanceNode is selected.
8414
- *
8415
- * When both {@link PerformanceNode#isObject} and {@link PerformanceNode#selected} are ````true```` the PerformanceNode will be
8416
- * registered by {@link PerformanceNode#id} in {@link Scene#selectedObjects}.
8421
+ * Gets if this PerformanceNode's edges are enhanced.
8417
8422
  *
8418
8423
  * @type {Boolean}
8419
8424
  */
8420
- get selected() {
8421
- return this._getFlag(ENTITY_FLAGS.SELECTED);
8425
+ get edges() {
8426
+ return this._getFlag(ENTITY_FLAGS.EDGES);
8422
8427
  }
8423
8428
 
8424
8429
  /**
@@ -8442,12 +8447,14 @@ class PerformanceNode {
8442
8447
  }
8443
8448
 
8444
8449
  /**
8445
- * Gets if this PerformanceNode's edges are enhanced.
8450
+ * Gets if this PerformanceNode is culled.
8451
+ *
8452
+ * Only rendered when {@link PerformanceNode#visible} is ````true```` and {@link PerformanceNode#culled} is ````false````.
8446
8453
  *
8447
8454
  * @type {Boolean}
8448
8455
  */
8449
- get edges() {
8450
- return this._getFlag(ENTITY_FLAGS.EDGES);
8456
+ get culled() {
8457
+ return this._getFlag(ENTITY_FLAGS.CULLED);
8451
8458
  }
8452
8459
 
8453
8460
  /**
@@ -8473,14 +8480,14 @@ class PerformanceNode {
8473
8480
  }
8474
8481
 
8475
8482
  /**
8476
- * Gets if this PerformanceNode is culled.
8483
+ * Gets if this PerformanceNode is clippable.
8477
8484
  *
8478
- * Only rendered when {@link PerformanceNode#visible} is ````true```` and {@link PerformanceNode#culled} is ````false````.
8485
+ * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.
8479
8486
  *
8480
8487
  * @type {Boolean}
8481
8488
  */
8482
- get culled() {
8483
- return this._getFlag(ENTITY_FLAGS.CULLED);
8489
+ get clippable() {
8490
+ return this._getFlag(ENTITY_FLAGS.CLIPPABLE);
8484
8491
  }
8485
8492
 
8486
8493
  /**
@@ -8506,14 +8513,12 @@ class PerformanceNode {
8506
8513
  }
8507
8514
 
8508
8515
  /**
8509
- * Gets if this PerformanceNode is clippable.
8510
- *
8511
- * Clipping is done by the {@link SectionPlane}s in {@link Scene#sectionPlanes}.
8516
+ * Gets if this PerformanceNode is included in boundary calculations.
8512
8517
  *
8513
8518
  * @type {Boolean}
8514
8519
  */
8515
- get clippable() {
8516
- return this._getFlag(ENTITY_FLAGS.CLIPPABLE);
8520
+ get collidable() {
8521
+ return this._getFlag(ENTITY_FLAGS.COLLIDABLE);
8517
8522
  }
8518
8523
 
8519
8524
  /**
@@ -8536,12 +8541,14 @@ class PerformanceNode {
8536
8541
  }
8537
8542
 
8538
8543
  /**
8539
- * Gets if this PerformanceNode is included in boundary calculations.
8544
+ * Gets if this PerformanceNode is pickable.
8545
+ *
8546
+ * Picking is done via calls to {@link Scene#pick}.
8540
8547
  *
8541
8548
  * @type {Boolean}
8542
8549
  */
8543
- get collidable() {
8544
- return this._getFlag(ENTITY_FLAGS.COLLIDABLE);
8550
+ get pickable() {
8551
+ return this._getFlag(ENTITY_FLAGS.PICKABLE);
8545
8552
  }
8546
8553
 
8547
8554
  /**
@@ -8566,14 +8573,21 @@ class PerformanceNode {
8566
8573
  }
8567
8574
 
8568
8575
  /**
8569
- * Gets if this PerformanceNode is pickable.
8576
+ * Gets the PerformanceNode's RGB colorize color.
8570
8577
  *
8571
- * Picking is done via calls to {@link Scene#pick}.
8578
+ * Each element of the color is in range ````[0..1]````.
8572
8579
  *
8573
- * @type {Boolean}
8580
+ * @type {Number[]}
8574
8581
  */
8575
- get pickable() {
8576
- return this._getFlag(ENTITY_FLAGS.PICKABLE);
8582
+ get colorize() { // [0..1, 0..1, 0..1]
8583
+ if (this.meshes.length === 0) {
8584
+ return null;
8585
+ }
8586
+ const colorize = this.meshes[0]._colorize;
8587
+ tempFloatRGB[0] = colorize[0] / 255.0; // Unquantize
8588
+ tempFloatRGB[1] = colorize[1] / 255.0;
8589
+ tempFloatRGB[2] = colorize[2] / 255.0;
8590
+ return tempFloatRGB;
8577
8591
  }
8578
8592
 
8579
8593
  /**
@@ -8604,21 +8618,18 @@ class PerformanceNode {
8604
8618
  }
8605
8619
 
8606
8620
  /**
8607
- * Gets the PerformanceNode's RGB colorize color.
8621
+ * Gets the PerformanceNode's opacity factor.
8608
8622
  *
8609
- * Each element of the color is in range ````[0..1]````.
8623
+ * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.
8610
8624
  *
8611
- * @type {Number[]}
8625
+ * @type {Number}
8612
8626
  */
8613
- get colorize() { // [0..1, 0..1, 0..1]
8614
- if (this.meshes.length === 0) {
8615
- return null;
8627
+ get opacity() {
8628
+ if (this.meshes.length > 0) {
8629
+ return (this.meshes[0]._colorize[3] / 255.0);
8630
+ } else {
8631
+ return 1.0;
8616
8632
  }
8617
- const colorize = this.meshes[0]._colorize;
8618
- tempFloatRGB[0] = colorize[0] / 255.0; // Unquantize
8619
- tempFloatRGB[1] = colorize[1] / 255.0;
8620
- tempFloatRGB[2] = colorize[2] / 255.0;
8621
- return tempFloatRGB;
8622
8633
  }
8623
8634
 
8624
8635
  /**
@@ -8661,18 +8672,14 @@ class PerformanceNode {
8661
8672
  }
8662
8673
 
8663
8674
  /**
8664
- * Gets the PerformanceNode's opacity factor.
8675
+ * Gets the PerformanceNode's 3D World-space offset.
8665
8676
  *
8666
- * This is a factor in range ````[0..1]```` which multiplies by the rendered fragment alphas.
8677
+ * Default value is ````[0,0,0]````.
8667
8678
  *
8668
- * @type {Number}
8679
+ * @type {Number[]}
8669
8680
  */
8670
- get opacity() {
8671
- if (this.meshes.length > 0) {
8672
- return (this.meshes[0]._colorize[3] / 255.0);
8673
- } else {
8674
- return 1.0;
8675
- }
8681
+ get offset() {
8682
+ return this._offset;
8676
8683
  }
8677
8684
 
8678
8685
  /**
@@ -8712,14 +8719,12 @@ class PerformanceNode {
8712
8719
  }
8713
8720
 
8714
8721
  /**
8715
- * Gets the PerformanceNode's 3D World-space offset.
8716
- *
8717
- * Default value is ````[0,0,0]````.
8722
+ * Gets if this PerformanceNode casts shadows.
8718
8723
  *
8719
- * @type {Number[]}
8724
+ * @type {Boolean}
8720
8725
  */
8721
- get offset() {
8722
- return this._offset;
8726
+ get castsShadow() { // TODO
8727
+ return false;
8723
8728
  }
8724
8729
 
8725
8730
  /**
@@ -8732,11 +8737,11 @@ class PerformanceNode {
8732
8737
  }
8733
8738
 
8734
8739
  /**
8735
- * Gets if this PerformanceNode casts shadows.
8740
+ * Whether or not this PerformanceNode can have shadows cast upon it
8736
8741
  *
8737
8742
  * @type {Boolean}
8738
8743
  */
8739
- get castsShadow() { // TODO
8744
+ get receivesShadow() { // TODO
8740
8745
  return false;
8741
8746
  }
8742
8747
 
@@ -8749,15 +8754,6 @@ class PerformanceNode {
8749
8754
 
8750
8755
  }
8751
8756
 
8752
- /**
8753
- * Whether or not this PerformanceNode can have shadows cast upon it
8754
- *
8755
- * @type {Boolean}
8756
- */
8757
- get receivesShadow() { // TODO
8758
- return false;
8759
- }
8760
-
8761
8757
  /**
8762
8758
  * Gets if Scalable Ambient Obscurance (SAO) will apply to this PerformanceNode.
8763
8759
  *
@@ -8770,6 +8766,10 @@ class PerformanceNode {
8770
8766
  return this.model.saoEnabled;
8771
8767
  }
8772
8768
 
8769
+ _getFlag(flag) {
8770
+ return !!(this._flags & flag);
8771
+ }
8772
+
8773
8773
  _finalize() {
8774
8774
  const scene = this.model.scene;
8775
8775
  if (this._isObject) {
@@ -8791,6 +8791,12 @@ class PerformanceNode {
8791
8791
  }
8792
8792
  }
8793
8793
 
8794
+ _finalize2() {
8795
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
8796
+ this.meshes[i]._finalize2();
8797
+ }
8798
+ }
8799
+
8794
8800
  _destroy() { // Called by PerformanceModel
8795
8801
  const scene = this.model.scene;
8796
8802
  if (this._isObject) {
@@ -8939,8 +8945,8 @@ function getPlaneRTCPos(dist, dir, rtcCenter, rtcPlanePos) {
8939
8945
  return rtcPlanePos;
8940
8946
  }
8941
8947
 
8942
- const tempVec4a$8 = math.vec4();
8943
- const tempVec4b$8 = math.vec4();
8948
+ const tempVec4a$a = math.vec4();
8949
+ const tempVec4b$a = math.vec4();
8944
8950
 
8945
8951
 
8946
8952
  /**
@@ -9101,12 +9107,12 @@ class Marker extends Component {
9101
9107
  this.fire("viewPos", this._viewPos);
9102
9108
  }
9103
9109
  if (this._canvasPosDirty) {
9104
- tempVec4a$8.set(this._viewPos);
9105
- tempVec4a$8[3] = 1.0;
9106
- math.transformPoint4(this.scene.camera.projMatrix, tempVec4a$8, tempVec4b$8);
9110
+ tempVec4a$a.set(this._viewPos);
9111
+ tempVec4a$a[3] = 1.0;
9112
+ math.transformPoint4(this.scene.camera.projMatrix, tempVec4a$a, tempVec4b$a);
9107
9113
  const aabb = this.scene.canvas.boundary;
9108
- this._canvasPos[0] = Math.floor((1 + tempVec4b$8[0] / tempVec4b$8[3]) * aabb[2] / 2);
9109
- this._canvasPos[1] = Math.floor((1 - tempVec4b$8[1] / tempVec4b$8[3]) * aabb[3] / 2);
9114
+ this._canvasPos[0] = Math.floor((1 + tempVec4b$a[0] / tempVec4b$a[3]) * aabb[2] / 2);
9115
+ this._canvasPos[1] = Math.floor((1 - tempVec4b$a[1] / tempVec4b$a[3]) * aabb[3] / 2);
9110
9116
  this._canvasPosDirty = false;
9111
9117
  this.fire("canvasPos", this._canvasPos);
9112
9118
  }
@@ -9622,26 +9628,21 @@ class AngleMeasurement extends Component {
9622
9628
 
9623
9629
  this._originDot = new Dot(this._container, {
9624
9630
  fillColor: this._color,
9625
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1: undefined
9631
+ zIndex: plugin.zIndex + 1
9626
9632
  });
9627
9633
  this._cornerDot = new Dot(this._container, {
9628
9634
  fillColor: this._color,
9629
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1: undefined
9635
+ zIndex: plugin.zIndex + 1
9630
9636
  });
9631
9637
  this._targetDot = new Dot(this._container, {
9632
9638
  fillColor: this._color,
9633
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 1: undefined
9639
+ zIndex: plugin.zIndex + 1
9634
9640
  });
9635
9641
 
9636
9642
  this._originWire = new Wire(this._container, {color: this._color || "blue", thickness: 1, zIndex: plugin.zIndex});
9637
9643
  this._targetWire = new Wire(this._container, {color: this._color || "red", thickness: 1, zIndex: plugin.zIndex});
9638
9644
 
9639
- this._angleLabel = new Label(this._container, {
9640
- fillColor: this._color || "#00BBFF",
9641
- prefix: "",
9642
- text: "",
9643
- zIndex: plugin.zIndex !== undefined ? plugin.zIndex + 2: undefined
9644
- });
9645
+ this._angleLabel = new Label(this._container, {fillColor: this._color || "#00BBFF", prefix: "", text: "", zIndex: plugin.zIndex + 2});
9645
9646
 
9646
9647
  this._wpDirty = false;
9647
9648
  this._vpDirty = false;
@@ -20776,6 +20777,17 @@ var compressPositions = (function () { // http://cg.postech.ac.kr/research/mesh_
20776
20777
  };
20777
20778
  })();
20778
20779
 
20780
+ function compressPosition(p, aabb, q) {
20781
+ const multiplier = new Float32Array([
20782
+ aabb[3] !== aabb[0] ? 65535 / (aabb[3] - aabb[0]) : 0,
20783
+ aabb[4] !== aabb[1] ? 65535 / (aabb[4] - aabb[1]) : 0,
20784
+ aabb[5] !== aabb[2] ? 65535 / (aabb[5] - aabb[2]) : 0
20785
+ ]);
20786
+ q[0] = Math.floor((p[0] - aabb[0]) * multiplier[0]);
20787
+ q[1] = Math.floor((p[1] - aabb[1]) * multiplier[1]);
20788
+ q[2] = Math.floor((p[2] - aabb[2]) * multiplier[2]);
20789
+ }
20790
+
20779
20791
  function decompressPosition(position, decodeMatrix, dest) {
20780
20792
  dest[0] = position[0] * decodeMatrix[0] + decodeMatrix[12];
20781
20793
  dest[1] = position[1] * decodeMatrix[5] + decodeMatrix[13];
@@ -20783,7 +20795,7 @@ function decompressPosition(position, decodeMatrix, dest) {
20783
20795
  return dest;
20784
20796
  }
20785
20797
 
20786
- function decompressAABB(aabb, decodeMatrix, dest=aabb) {
20798
+ function decompressAABB(aabb, decodeMatrix, dest = aabb) {
20787
20799
  dest[0] = aabb[0] * decodeMatrix[0] + decodeMatrix[12];
20788
20800
  dest[1] = aabb[1] * decodeMatrix[5] + decodeMatrix[13];
20789
20801
  dest[2] = aabb[2] * decodeMatrix[10] + decodeMatrix[14];
@@ -21027,6 +21039,7 @@ const geometryCompressionUtils = {
21027
21039
  getPositionsBounds: getPositionsBounds,
21028
21040
  createPositionsDecodeMatrix: createPositionsDecodeMatrix,
21029
21041
  compressPositions: compressPositions,
21042
+ compressPosition:compressPosition,
21030
21043
  decompressPositions: decompressPositions,
21031
21044
  decompressPosition: decompressPosition,
21032
21045
  decompressAABB: decompressAABB,
@@ -39820,6 +39833,15 @@ class PerformanceMesh {
39820
39833
  this._layer.initFlags(this._portionId, entityFlags, this._transparent);
39821
39834
  }
39822
39835
 
39836
+ /**
39837
+ * @private
39838
+ */
39839
+ _finalize2() {
39840
+ if (this._layer.flushInitFlags) {
39841
+ this._layer.flushInitFlags();
39842
+ }
39843
+ }
39844
+
39823
39845
  /**
39824
39846
  * @private
39825
39847
  */
@@ -45674,8 +45696,8 @@ function dot(p, vec3) { // Dot product of a normal in an array against a candida
45674
45696
 
45675
45697
  const tempMat4$2 = math.mat4();
45676
45698
  const tempMat4b = math.mat4();
45677
- const tempVec4a$7 = math.vec4([0, 0, 0, 1]);
45678
- const tempVec4b$7 = math.vec4([0, 0, 0, 1]);
45699
+ const tempVec4a$9 = math.vec4([0, 0, 0, 1]);
45700
+ const tempVec4b$9 = math.vec4([0, 0, 0, 1]);
45679
45701
  const tempVec4c$7 = math.vec4([0, 0, 0, 1]);
45680
45702
  const tempOBB3$2 = math.OBB3();
45681
45703
 
@@ -45750,6 +45772,8 @@ class TrianglesBatchingLayer {
45750
45772
  this._modelAABB = math.collapseAABB3(); // Model-space AABB
45751
45773
  this._portions = [];
45752
45774
 
45775
+ this._numVerts = 0;
45776
+
45753
45777
  this._finalized = false;
45754
45778
 
45755
45779
  if (cfg.positionsDecodeMatrix) {
@@ -45873,23 +45897,23 @@ class TrianglesBatchingLayer {
45873
45897
 
45874
45898
  for (let i = positionsBase, len = positionsBase + lenPositions; i < len; i += 3) {
45875
45899
 
45876
- tempVec4a$7[0] = buffer.positions[i + 0];
45877
- tempVec4a$7[1] = buffer.positions[i + 1];
45878
- tempVec4a$7[2] = buffer.positions[i + 2];
45900
+ tempVec4a$9[0] = buffer.positions[i + 0];
45901
+ tempVec4a$9[1] = buffer.positions[i + 1];
45902
+ tempVec4a$9[2] = buffer.positions[i + 2];
45879
45903
 
45880
- math.transformPoint4(meshMatrix, tempVec4a$7, tempVec4b$7);
45904
+ math.transformPoint4(meshMatrix, tempVec4a$9, tempVec4b$9);
45881
45905
 
45882
- buffer.positions[i + 0] = tempVec4b$7[0];
45883
- buffer.positions[i + 1] = tempVec4b$7[1];
45884
- buffer.positions[i + 2] = tempVec4b$7[2];
45906
+ buffer.positions[i + 0] = tempVec4b$9[0];
45907
+ buffer.positions[i + 1] = tempVec4b$9[1];
45908
+ buffer.positions[i + 2] = tempVec4b$9[2];
45885
45909
 
45886
- math.expandAABB3Point3(this._modelAABB, tempVec4b$7);
45910
+ math.expandAABB3Point3(this._modelAABB, tempVec4b$9);
45887
45911
 
45888
45912
  if (worldMatrix) {
45889
- math.transformPoint4(worldMatrix, tempVec4b$7, tempVec4c$7);
45913
+ math.transformPoint4(worldMatrix, tempVec4b$9, tempVec4c$7);
45890
45914
  math.expandAABB3Point3(worldAABB, tempVec4c$7);
45891
45915
  } else {
45892
- math.expandAABB3Point3(worldAABB, tempVec4b$7);
45916
+ math.expandAABB3Point3(worldAABB, tempVec4b$9);
45893
45917
  }
45894
45918
  }
45895
45919
 
@@ -45897,17 +45921,17 @@ class TrianglesBatchingLayer {
45897
45921
 
45898
45922
  for (let i = positionsBase, len = positionsBase + lenPositions; i < len; i += 3) {
45899
45923
 
45900
- tempVec4a$7[0] = buffer.positions[i + 0];
45901
- tempVec4a$7[1] = buffer.positions[i + 1];
45902
- tempVec4a$7[2] = buffer.positions[i + 2];
45924
+ tempVec4a$9[0] = buffer.positions[i + 0];
45925
+ tempVec4a$9[1] = buffer.positions[i + 1];
45926
+ tempVec4a$9[2] = buffer.positions[i + 2];
45903
45927
 
45904
- math.expandAABB3Point3(this._modelAABB, tempVec4a$7);
45928
+ math.expandAABB3Point3(this._modelAABB, tempVec4a$9);
45905
45929
 
45906
45930
  if (worldMatrix) {
45907
- math.transformPoint4(worldMatrix, tempVec4a$7, tempVec4b$7);
45908
- math.expandAABB3Point3(worldAABB, tempVec4b$7);
45931
+ math.transformPoint4(worldMatrix, tempVec4a$9, tempVec4b$9);
45932
+ math.expandAABB3Point3(worldAABB, tempVec4b$9);
45909
45933
  } else {
45910
- math.expandAABB3Point3(worldAABB, tempVec4a$7);
45934
+ math.expandAABB3Point3(worldAABB, tempVec4a$9);
45911
45935
  }
45912
45936
  }
45913
45937
  }
@@ -46032,6 +46056,8 @@ class TrianglesBatchingLayer {
46032
46056
  this._numPortions++;
46033
46057
  this.model.numPortions++;
46034
46058
 
46059
+ this._numVerts += portion.numVerts;
46060
+
46035
46061
  return portionId;
46036
46062
  }
46037
46063
 
@@ -46164,8 +46190,14 @@ class TrianglesBatchingLayer {
46164
46190
  this._numTransparentLayerPortions++;
46165
46191
  this.model.numTransparentLayerPortions++;
46166
46192
  }
46167
- this._setFlags(portionId, flags, meshTransparent);
46168
- this._setFlags2(portionId, flags);
46193
+ const deferred = true;
46194
+ this._setFlags(portionId, flags, meshTransparent, deferred);
46195
+ this._setFlags2(portionId, flags, deferred);
46196
+ }
46197
+
46198
+ flushInitFlags() {
46199
+ this._setDeferredFlags();
46200
+ this._setDeferredFlags2();
46169
46201
  }
46170
46202
 
46171
46203
  setVisible(portionId, flags, transparent) {
@@ -46323,7 +46355,7 @@ class TrianglesBatchingLayer {
46323
46355
  this._setFlags(portionId, flags, transparent);
46324
46356
  }
46325
46357
 
46326
- _setFlags(portionId, flags, transparent) {
46358
+ _setFlags(portionId, flags, transparent, deferred = false) {
46327
46359
 
46328
46360
  if (!this._finalized) {
46329
46361
  throw "Not finalized";
@@ -46335,7 +46367,6 @@ class TrianglesBatchingLayer {
46335
46367
  const numVerts = portion.numVerts;
46336
46368
  const firstFlag = vertexBase * 4;
46337
46369
  const lenFlags = numVerts * 4;
46338
- const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
46339
46370
 
46340
46371
  const visible = !!(flags & ENTITY_FLAGS.VISIBLE);
46341
46372
  const xrayed = !!(flags & ENTITY_FLAGS.XRAYED);
@@ -46398,19 +46429,37 @@ class TrianglesBatchingLayer {
46398
46429
 
46399
46430
  let f3 = (visible && !culled && pickable) ? RENDER_PASSES.PICK : RENDER_PASSES.NOT_RENDERED;
46400
46431
 
46401
- for (let i = 0; i < lenFlags; i += 4) {
46402
- tempArray[i + 0] = f0; // x - normal fill
46403
- tempArray[i + 1] = f1; // y - emphasis fill
46404
- tempArray[i + 2] = f2; // z - edges
46405
- tempArray[i + 3] = f3; // w - pick
46432
+ if (deferred) {
46433
+ // Avoid zillions of individual WebGL bufferSubData calls - buffer them to apply in one shot
46434
+ if (!this._deferredFlagValues) {
46435
+ this._deferredFlagValues = new Uint8Array(this._numVerts * 4);
46436
+ }
46437
+ for (let i = firstFlag, len = (firstFlag + lenFlags); i < len; i += 4) {
46438
+ this._deferredFlagValues[i + 0] = f0;
46439
+ this._deferredFlagValues[i + 1] = f1;
46440
+ this._deferredFlagValues[i + 2] = f2;
46441
+ this._deferredFlagValues[i + 3] = f3;
46442
+ }
46443
+ } else if (this._state.flagsBuf) {
46444
+ const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
46445
+ for (let i = 0; i < lenFlags; i += 4) {
46446
+ tempArray[i + 0] = f0; // x - normal fill
46447
+ tempArray[i + 1] = f1; // y - emphasis fill
46448
+ tempArray[i + 2] = f2; // z - edges
46449
+ tempArray[i + 3] = f3; // w - pick
46450
+ }
46451
+ this._state.flagsBuf.setData(tempArray, firstFlag, lenFlags);
46406
46452
  }
46453
+ }
46407
46454
 
46408
- if (this._state.flagsBuf) {
46409
- this._state.flagsBuf.setData(tempArray, firstFlag, lenFlags);
46455
+ _setDeferredFlags() {
46456
+ if (this._deferredFlagValues) {
46457
+ this._state.flagsBuf.setData(this._deferredFlagValues);
46458
+ this._deferredFlagValues = null;
46410
46459
  }
46411
46460
  }
46412
46461
 
46413
- _setFlags2(portionId, flags) {
46462
+ _setFlags2(portionId, flags, deferred = false) {
46414
46463
 
46415
46464
  if (!this._finalized) {
46416
46465
  throw "Not finalized";
@@ -46422,16 +46471,28 @@ class TrianglesBatchingLayer {
46422
46471
  const numVerts = portion.numVerts;
46423
46472
  const firstFlag = vertexBase * 4;
46424
46473
  const lenFlags = numVerts * 4;
46425
- const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
46426
-
46427
46474
  const clippable = !!(flags & ENTITY_FLAGS.CLIPPABLE) ? 255 : 0;
46428
46475
 
46429
- for (let i = 0; i < lenFlags; i += 4) {
46430
- tempArray[i + 0] = clippable;
46476
+ if (deferred) {
46477
+ if (!this._setDeferredFlag2Values) {
46478
+ this._setDeferredFlag2Values = new Uint8Array(this._numVerts * 4);
46479
+ }
46480
+ for (let i = firstFlag, len = (firstFlag + lenFlags); i < len; i += 4) {
46481
+ this._setDeferredFlag2Values[i] = clippable;
46482
+ }
46483
+ } else if (this._state.flags2Buf) {
46484
+ const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
46485
+ for (let i = 0; i < lenFlags; i += 4) {
46486
+ tempArray[i + 0] = clippable;
46487
+ }
46488
+ this._state.flags2Buf.setData(tempArray, firstFlag, lenFlags);
46431
46489
  }
46490
+ }
46432
46491
 
46433
- if (this._state.flags2Buf) {
46434
- this._state.flags2Buf.setData(tempArray, firstFlag, lenFlags);
46492
+ _setDeferredFlags2() {
46493
+ if (this._setDeferredFlag2Values) {
46494
+ this._state.flags2Buf.setData(this._setDeferredFlag2Values);
46495
+ this._setDeferredFlag2Values = null;
46435
46496
  }
46436
46497
  }
46437
46498
 
@@ -52814,8 +52875,8 @@ function getInstancingRenderers$1(scene) {
52814
52875
  const bigIndicesSupported$4 = WEBGL_INFO$1.SUPPORTED_EXTENSIONS["OES_element_index_uint"];
52815
52876
 
52816
52877
  const tempUint8Vec4$2 = new Uint8Array(4);
52817
- const tempVec4a$6 = math.vec4([0, 0, 0, 1]);
52818
- const tempVec4b$6 = math.vec4([0, 0, 0, 1]);
52878
+ const tempVec4a$8 = math.vec4([0, 0, 0, 1]);
52879
+ const tempVec4b$8 = math.vec4([0, 0, 0, 1]);
52819
52880
  const tempVec4c$6 = math.vec4([0, 0, 0, 1]);
52820
52881
  const tempVec3fa$2 = new Float32Array(3);
52821
52882
 
@@ -53094,15 +53155,15 @@ class TrianglesInstancingLayer {
53094
53155
  const obb = this._state.obb;
53095
53156
  const lenPositions = obb.length;
53096
53157
  for (let i = 0; i < lenPositions; i += 4) {
53097
- tempVec4a$6[0] = obb[i + 0];
53098
- tempVec4a$6[1] = obb[i + 1];
53099
- tempVec4a$6[2] = obb[i + 2];
53100
- math.transformPoint4(meshMatrix, tempVec4a$6, tempVec4b$6);
53158
+ tempVec4a$8[0] = obb[i + 0];
53159
+ tempVec4a$8[1] = obb[i + 1];
53160
+ tempVec4a$8[2] = obb[i + 2];
53161
+ math.transformPoint4(meshMatrix, tempVec4a$8, tempVec4b$8);
53101
53162
  if (worldMatrix) {
53102
- math.transformPoint4(worldMatrix, tempVec4b$6, tempVec4c$6);
53163
+ math.transformPoint4(worldMatrix, tempVec4b$8, tempVec4c$6);
53103
53164
  math.expandAABB3Point3(worldAABB, tempVec4c$6);
53104
53165
  } else {
53105
- math.expandAABB3Point3(worldAABB, tempVec4b$6);
53166
+ math.expandAABB3Point3(worldAABB, tempVec4b$8);
53106
53167
  }
53107
53168
  }
53108
53169
 
@@ -54641,8 +54702,8 @@ class LinesBatchingBuffer {
54641
54702
  }
54642
54703
  }
54643
54704
 
54644
- const tempVec4a$5 = math.vec4([0, 0, 0, 1]);
54645
- const tempVec4b$5 = math.vec4([0, 0, 0, 1]);
54705
+ const tempVec4a$7 = math.vec4([0, 0, 0, 1]);
54706
+ const tempVec4b$7 = math.vec4([0, 0, 0, 1]);
54646
54707
  const tempVec4c$5 = math.vec4([0, 0, 0, 1]);
54647
54708
  const tempOBB3$1 = math.OBB3();
54648
54709
 
@@ -54699,6 +54760,8 @@ class LinesBatchingLayer {
54699
54760
  this._modelAABB = math.collapseAABB3(); // Model-space AABB
54700
54761
  this._portions = [];
54701
54762
 
54763
+ this._numVerts = 0;
54764
+
54702
54765
  this._finalized = false;
54703
54766
  this._positionsDecodeMatrix = cfg.positionsDecodeMatrix;
54704
54767
  this._preCompressed = (!!this._positionsDecodeMatrix);
@@ -54800,23 +54863,23 @@ class LinesBatchingLayer {
54800
54863
 
54801
54864
  for (let i = positionsBase, len = positionsBase + lenPositions; i < len; i += 3) {
54802
54865
 
54803
- tempVec4a$5[0] = buffer.positions[i + 0];
54804
- tempVec4a$5[1] = buffer.positions[i + 1];
54805
- tempVec4a$5[2] = buffer.positions[i + 2];
54866
+ tempVec4a$7[0] = buffer.positions[i + 0];
54867
+ tempVec4a$7[1] = buffer.positions[i + 1];
54868
+ tempVec4a$7[2] = buffer.positions[i + 2];
54806
54869
 
54807
- math.transformPoint4(meshMatrix, tempVec4a$5, tempVec4b$5);
54870
+ math.transformPoint4(meshMatrix, tempVec4a$7, tempVec4b$7);
54808
54871
 
54809
- buffer.positions[i + 0] = tempVec4b$5[0];
54810
- buffer.positions[i + 1] = tempVec4b$5[1];
54811
- buffer.positions[i + 2] = tempVec4b$5[2];
54872
+ buffer.positions[i + 0] = tempVec4b$7[0];
54873
+ buffer.positions[i + 1] = tempVec4b$7[1];
54874
+ buffer.positions[i + 2] = tempVec4b$7[2];
54812
54875
 
54813
- math.expandAABB3Point3(this._modelAABB, tempVec4b$5);
54876
+ math.expandAABB3Point3(this._modelAABB, tempVec4b$7);
54814
54877
 
54815
54878
  if (worldMatrix) {
54816
- math.transformPoint4(worldMatrix, tempVec4b$5, tempVec4c$5);
54879
+ math.transformPoint4(worldMatrix, tempVec4b$7, tempVec4c$5);
54817
54880
  math.expandAABB3Point3(worldAABB, tempVec4c$5);
54818
54881
  } else {
54819
- math.expandAABB3Point3(worldAABB, tempVec4b$5);
54882
+ math.expandAABB3Point3(worldAABB, tempVec4b$7);
54820
54883
  }
54821
54884
  }
54822
54885
 
@@ -54824,17 +54887,17 @@ class LinesBatchingLayer {
54824
54887
 
54825
54888
  for (let i = positionsBase, len = positionsBase + lenPositions; i < len; i += 3) {
54826
54889
 
54827
- tempVec4a$5[0] = buffer.positions[i + 0];
54828
- tempVec4a$5[1] = buffer.positions[i + 1];
54829
- tempVec4a$5[2] = buffer.positions[i + 2];
54890
+ tempVec4a$7[0] = buffer.positions[i + 0];
54891
+ tempVec4a$7[1] = buffer.positions[i + 1];
54892
+ tempVec4a$7[2] = buffer.positions[i + 2];
54830
54893
 
54831
- math.expandAABB3Point3(this._modelAABB, tempVec4a$5);
54894
+ math.expandAABB3Point3(this._modelAABB, tempVec4a$7);
54832
54895
 
54833
54896
  if (worldMatrix) {
54834
- math.transformPoint4(worldMatrix, tempVec4a$5, tempVec4b$5);
54835
- math.expandAABB3Point3(worldAABB, tempVec4b$5);
54897
+ math.transformPoint4(worldMatrix, tempVec4a$7, tempVec4b$7);
54898
+ math.expandAABB3Point3(worldAABB, tempVec4b$7);
54836
54899
  } else {
54837
- math.expandAABB3Point3(worldAABB, tempVec4a$5);
54900
+ math.expandAABB3Point3(worldAABB, tempVec4a$7);
54838
54901
  }
54839
54902
  }
54840
54903
  }
@@ -54889,6 +54952,8 @@ class LinesBatchingLayer {
54889
54952
  this._numPortions++;
54890
54953
  this.model.numPortions++;
54891
54954
 
54955
+ this._numVerts += numVerts;
54956
+
54892
54957
  return portionId;
54893
54958
  }
54894
54959
 
@@ -54914,7 +54979,7 @@ class LinesBatchingLayer {
54914
54979
  state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, positions, buffer.positions.length, 3, gl.STATIC_DRAW);
54915
54980
  } else {
54916
54981
  const positions = new Float32Array(buffer.positions);
54917
- const quantizedPositions = quantizePositions(positions, this._modelAABB, state.positionsDecodeMatrix);
54982
+ const quantizedPositions = quantizePositions(positions, this._modelAABB, state.positionsDecodeMatrix);
54918
54983
  state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, quantizedPositions, buffer.positions.length, 3, gl.STATIC_DRAW);
54919
54984
  }
54920
54985
  }
@@ -54990,8 +55055,14 @@ class LinesBatchingLayer {
54990
55055
  this._numTransparentLayerPortions++;
54991
55056
  this.model.numTransparentLayerPortions++;
54992
55057
  }
54993
- this._setFlags(portionId, flags, meshTransparent);
54994
- this._setFlags2(portionId, flags);
55058
+ const deferred = true;
55059
+ this._setFlags(portionId, flags, meshTransparent, deferred);
55060
+ this._setFlags2(portionId, flags, deferred);
55061
+ }
55062
+
55063
+ flushInitFlags() {
55064
+ this._setDeferredFlags();
55065
+ this._setDeferredFlags2();
54995
55066
  }
54996
55067
 
54997
55068
  setVisible(portionId, flags, transparent) {
@@ -55146,7 +55217,7 @@ class LinesBatchingLayer {
55146
55217
  this._setFlags(portionId, flags, transparent);
55147
55218
  }
55148
55219
 
55149
- _setFlags(portionId, flags, transparent) {
55220
+ _setFlags(portionId, flags, transparent, deferred = false) {
55150
55221
 
55151
55222
  if (!this._finalized) {
55152
55223
  throw "Not finalized";
@@ -55157,7 +55228,7 @@ class LinesBatchingLayer {
55157
55228
  const numVerts = this._portions[portionsIdx + 1];
55158
55229
  const firstFlag = vertexBase * 4;
55159
55230
  const lenFlags = numVerts * 4;
55160
- const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
55231
+ this._scratchMemory.getUInt8Array(lenFlags);
55161
55232
 
55162
55233
  const visible = !!(flags & ENTITY_FLAGS.VISIBLE);
55163
55234
  const xrayed = !!(flags & ENTITY_FLAGS.XRAYED);
@@ -55197,18 +55268,36 @@ class LinesBatchingLayer {
55197
55268
  // Pick
55198
55269
 
55199
55270
  let f3 = (visible && !culled && pickable) ? RENDER_PASSES.PICK : RENDER_PASSES.NOT_RENDERED;
55200
-
55201
- for (let i = 0; i < lenFlags; i += 4) {
55202
- tempArray[i + 0] = f0; // x - color
55203
- tempArray[i + 1] = f1; // y - silhouette - select/highlight/xray
55204
- tempArray[i + 2] = 0; // z - edges
55205
- tempArray[i + 3] = f3; // w - pickable
55271
+ if (deferred) {
55272
+ if (!this._deferredFlagValues) {
55273
+ this._deferredFlagValues = new Uint8Array(this._numVerts * 4);
55274
+ }
55275
+ for (let i = firstFlag, len = (firstFlag + lenFlags); i < len; i += 4) {
55276
+ this._deferredFlagValues[i + 0] = f0;
55277
+ this._deferredFlagValues[i + 1] = f1;
55278
+ this._deferredFlagValues[i + 2] = 0;
55279
+ this._deferredFlagValues[i + 3] = f3;
55280
+ }
55281
+ } else if (this._state.flagsBuf) {
55282
+ const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
55283
+ for (let i = 0; i < lenFlags; i += 4) {
55284
+ tempArray[i + 0] = f0; // x - color
55285
+ tempArray[i + 1] = f1; // y - silhouette - select/highlight/xray
55286
+ tempArray[i + 2] = 0; // z - edges
55287
+ tempArray[i + 3] = f3; // w - pickable
55288
+ }
55289
+ this._state.flagsBuf.setData(tempArray, firstFlag, lenFlags);
55206
55290
  }
55291
+ }
55207
55292
 
55208
- this._state.flagsBuf.setData(tempArray, firstFlag, lenFlags);
55293
+ _setDeferredFlags() {
55294
+ if (this._deferredFlagValues) {
55295
+ this._state.flagsBuf.setData(this._deferredFlagValues);
55296
+ this._deferredFlagValues = null;
55297
+ }
55209
55298
  }
55210
55299
 
55211
- _setFlags2(portionId, flags) {
55300
+ _setFlags2(portionId, flags, deferred = false) {
55212
55301
  if (!this._finalized) {
55213
55302
  throw "Not finalized";
55214
55303
  }
@@ -55217,12 +55306,28 @@ class LinesBatchingLayer {
55217
55306
  const numVerts = this._portions[portionsIdx + 1];
55218
55307
  const firstFlag = vertexBase * 4;
55219
55308
  const lenFlags = numVerts * 4;
55220
- const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
55221
55309
  const clippable = !!(flags & ENTITY_FLAGS.CLIPPABLE) ? 255 : 0;
55222
- for (let i = 0; i < lenFlags; i += 4) {
55223
- tempArray[i + 0] = clippable;
55310
+ if (deferred) {
55311
+ if (!this._setDeferredFlag2Values) {
55312
+ this._setDeferredFlag2Values = new Uint8Array(this._numVerts * 4);
55313
+ }
55314
+ for (let i = firstFlag, len = (firstFlag + lenFlags); i < len; i += 4) {
55315
+ this._setDeferredFlag2Values[i] = clippable;
55316
+ }
55317
+ } else {
55318
+ const tempArray = this._scratchMemory.getUInt8Array(lenFlags);
55319
+ for (let i = 0; i < lenFlags; i += 4) {
55320
+ tempArray[i + 0] = clippable;
55321
+ }
55322
+ this._state.flags2Buf.setData(tempArray, firstFlag, lenFlags);
55323
+ }
55324
+ }
55325
+
55326
+ _setDeferredFlags2() {
55327
+ if (this._setDeferredFlag2Values) {
55328
+ this._state.flags2Buf.setData(this._setDeferredFlag2Values);
55329
+ this._setDeferredFlag2Values = null;
55224
55330
  }
55225
- this._state.flags2Buf.setData(tempArray, firstFlag, lenFlags);
55226
55331
  }
55227
55332
 
55228
55333
  setOffset(portionId, offset) {
@@ -56141,8 +56246,8 @@ const bigIndicesSupported$2 = WEBGL_INFO$1.SUPPORTED_EXTENSIONS["OES_element_ind
56141
56246
 
56142
56247
  const tempUint8Vec4$1 = new Uint8Array(4);
56143
56248
 
56144
- const tempVec4a$4 = math.vec4([0, 0, 0, 1]);
56145
- const tempVec4b$4 = math.vec4([0, 0, 0, 1]);
56249
+ const tempVec4a$6 = math.vec4([0, 0, 0, 1]);
56250
+ const tempVec4b$6 = math.vec4([0, 0, 0, 1]);
56146
56251
  const tempVec4c$4 = math.vec4([0, 0, 0, 1]);
56147
56252
 
56148
56253
  const tempVec3fa$1 = new Float32Array(3);
@@ -56325,15 +56430,15 @@ class LinesInstancingLayer {
56325
56430
  const obb = this._state.obb;
56326
56431
  const lenPositions = obb.length;
56327
56432
  for (let i = 0; i < lenPositions; i += 4) {
56328
- tempVec4a$4[0] = obb[i + 0];
56329
- tempVec4a$4[1] = obb[i + 1];
56330
- tempVec4a$4[2] = obb[i + 2];
56331
- math.transformPoint4(meshMatrix, tempVec4a$4, tempVec4b$4);
56433
+ tempVec4a$6[0] = obb[i + 0];
56434
+ tempVec4a$6[1] = obb[i + 1];
56435
+ tempVec4a$6[2] = obb[i + 2];
56436
+ math.transformPoint4(meshMatrix, tempVec4a$6, tempVec4b$6);
56332
56437
  if (worldMatrix) {
56333
- math.transformPoint4(worldMatrix, tempVec4b$4, tempVec4c$4);
56438
+ math.transformPoint4(worldMatrix, tempVec4b$6, tempVec4c$4);
56334
56439
  math.expandAABB3Point3(worldAABB, tempVec4c$4);
56335
56440
  } else {
56336
- math.expandAABB3Point3(worldAABB, tempVec4b$4);
56441
+ math.expandAABB3Point3(worldAABB, tempVec4b$6);
56337
56442
  }
56338
56443
  }
56339
56444
 
@@ -58631,8 +58736,8 @@ class PointsBatchingBuffer {
58631
58736
 
58632
58737
  const tempVec3a$g = math.vec4();
58633
58738
  const tempVec3b$5 = math.vec4();
58634
- const tempVec4a$3 = math.vec4([0, 0, 0, 1]);
58635
- const tempVec4b$3 = math.vec4([0, 0, 0, 1]);
58739
+ const tempVec4a$5 = math.vec4([0, 0, 0, 1]);
58740
+ const tempVec4b$5 = math.vec4([0, 0, 0, 1]);
58636
58741
  const tempVec4c$3 = math.vec4([0, 0, 0, 1]);
58637
58742
  const tempOBB3 = math.OBB3();
58638
58743
 
@@ -58794,23 +58899,23 @@ class PointsBatchingLayer {
58794
58899
 
58795
58900
  for (let i = positionsBase, len = positionsBase + lenPositions; i < len; i += 3) {
58796
58901
 
58797
- tempVec4a$3[0] = buffer.positions[i + 0];
58798
- tempVec4a$3[1] = buffer.positions[i + 1];
58799
- tempVec4a$3[2] = buffer.positions[i + 2];
58902
+ tempVec4a$5[0] = buffer.positions[i + 0];
58903
+ tempVec4a$5[1] = buffer.positions[i + 1];
58904
+ tempVec4a$5[2] = buffer.positions[i + 2];
58800
58905
 
58801
- math.transformPoint4(meshMatrix, tempVec4a$3, tempVec4b$3);
58906
+ math.transformPoint4(meshMatrix, tempVec4a$5, tempVec4b$5);
58802
58907
 
58803
- buffer.positions[i + 0] = tempVec4b$3[0];
58804
- buffer.positions[i + 1] = tempVec4b$3[1];
58805
- buffer.positions[i + 2] = tempVec4b$3[2];
58908
+ buffer.positions[i + 0] = tempVec4b$5[0];
58909
+ buffer.positions[i + 1] = tempVec4b$5[1];
58910
+ buffer.positions[i + 2] = tempVec4b$5[2];
58806
58911
 
58807
- math.expandAABB3Point3(this._modelAABB, tempVec4b$3);
58912
+ math.expandAABB3Point3(this._modelAABB, tempVec4b$5);
58808
58913
 
58809
58914
  if (worldMatrix) {
58810
- math.transformPoint4(worldMatrix, tempVec4b$3, tempVec4c$3);
58915
+ math.transformPoint4(worldMatrix, tempVec4b$5, tempVec4c$3);
58811
58916
  math.expandAABB3Point3(worldAABB, tempVec4c$3);
58812
58917
  } else {
58813
- math.expandAABB3Point3(worldAABB, tempVec4b$3);
58918
+ math.expandAABB3Point3(worldAABB, tempVec4b$5);
58814
58919
  }
58815
58920
  }
58816
58921
 
@@ -58818,17 +58923,17 @@ class PointsBatchingLayer {
58818
58923
 
58819
58924
  for (let i = positionsBase, len = positionsBase + lenPositions; i < len; i += 3) {
58820
58925
 
58821
- tempVec4a$3[0] = buffer.positions[i + 0];
58822
- tempVec4a$3[1] = buffer.positions[i + 1];
58823
- tempVec4a$3[2] = buffer.positions[i + 2];
58926
+ tempVec4a$5[0] = buffer.positions[i + 0];
58927
+ tempVec4a$5[1] = buffer.positions[i + 1];
58928
+ tempVec4a$5[2] = buffer.positions[i + 2];
58824
58929
 
58825
- math.expandAABB3Point3(this._modelAABB, tempVec4a$3);
58930
+ math.expandAABB3Point3(this._modelAABB, tempVec4a$5);
58826
58931
 
58827
58932
  if (worldMatrix) {
58828
- math.transformPoint4(worldMatrix, tempVec4a$3, tempVec4b$3);
58829
- math.expandAABB3Point3(worldAABB, tempVec4b$3);
58933
+ math.transformPoint4(worldMatrix, tempVec4a$5, tempVec4b$5);
58934
+ math.expandAABB3Point3(worldAABB, tempVec4b$5);
58830
58935
  } else {
58831
- math.expandAABB3Point3(worldAABB, tempVec4a$3);
58936
+ math.expandAABB3Point3(worldAABB, tempVec4a$5);
58832
58937
  }
58833
58938
  }
58834
58939
  }
@@ -62058,8 +62163,8 @@ function getPointsInstancingRenderers(scene) {
62058
62163
  }
62059
62164
 
62060
62165
  const tempUint8Vec4 = new Uint8Array(4);
62061
- const tempVec4a$2 = math.vec4([0, 0, 0, 1]);
62062
- const tempVec4b$2 = math.vec4([0, 0, 0, 1]);
62166
+ const tempVec4a$4 = math.vec4([0, 0, 0, 1]);
62167
+ const tempVec4b$4 = math.vec4([0, 0, 0, 1]);
62063
62168
  const tempVec4c$2 = math.vec4([0, 0, 0, 1]);
62064
62169
  const tempVec3fa = new Float32Array(3);
62065
62170
 
@@ -62252,15 +62357,15 @@ class PointsInstancingLayer {
62252
62357
  const obb = this._state.obb;
62253
62358
  const lenPositions = obb.length;
62254
62359
  for (let i = 0; i < lenPositions; i += 4) {
62255
- tempVec4a$2[0] = obb[i + 0];
62256
- tempVec4a$2[1] = obb[i + 1];
62257
- tempVec4a$2[2] = obb[i + 2];
62258
- math.transformPoint4(meshMatrix, tempVec4a$2, tempVec4b$2);
62360
+ tempVec4a$4[0] = obb[i + 0];
62361
+ tempVec4a$4[1] = obb[i + 1];
62362
+ tempVec4a$4[2] = obb[i + 2];
62363
+ math.transformPoint4(meshMatrix, tempVec4a$4, tempVec4b$4);
62259
62364
  if (worldMatrix) {
62260
- math.transformPoint4(worldMatrix, tempVec4b$2, tempVec4c$2);
62365
+ math.transformPoint4(worldMatrix, tempVec4b$4, tempVec4c$2);
62261
62366
  math.expandAABB3Point3(worldAABB, tempVec4c$2);
62262
62367
  } else {
62263
- math.expandAABB3Point3(worldAABB, tempVec4b$2);
62368
+ math.expandAABB3Point3(worldAABB, tempVec4b$4);
62264
62369
  }
62265
62370
  }
62266
62371
 
@@ -63786,6 +63891,14 @@ class PerformanceModel extends Component {
63786
63891
  return true;
63787
63892
  }
63788
63893
 
63894
+ /**
63895
+ * Returns the {@link Entity}s in this PerformanceModel.
63896
+ * @returns {*|{}}
63897
+ */
63898
+ get objects() {
63899
+ return this._nodes;
63900
+ }
63901
+
63789
63902
  /**
63790
63903
  * Gets the 3D World-space origin for this PerformanceModel.
63791
63904
  *
@@ -65045,6 +65158,12 @@ class PerformanceModel extends Component {
65045
65158
  node._finalize();
65046
65159
  }
65047
65160
 
65161
+ for (let i = 0, len = this._nodeList.length; i < len; i++) {
65162
+ const node = this._nodeList[i];
65163
+ node._finalize2();
65164
+ }
65165
+
65166
+
65048
65167
  // Sort layers to reduce WebGL shader switching when rendering them
65049
65168
 
65050
65169
  this._layerList.sort((a, b) => {
@@ -88556,6 +88675,9 @@ if (!pako$1.inflate) { // See https://github.com/nodeca/pako/issues/97
88556
88675
  pako$1 = pako$1.default;
88557
88676
  }
88558
88677
 
88678
+ const tempVec4a$3 = math.vec4();
88679
+ const tempVec4b$3 = math.vec4();
88680
+
88559
88681
  function extract$1(elements) {
88560
88682
 
88561
88683
  return {
@@ -88658,10 +88780,10 @@ const decompressColor$1 = (function () {
88658
88780
 
88659
88781
  function convertColorsRGBToRGBA(colorsRGB) {
88660
88782
  const colorsRGBA = [];
88661
- for (let i = 0, len = colorsRGB.length; i < len; i+=3) {
88783
+ for (let i = 0, len = colorsRGB.length; i < len; i += 3) {
88662
88784
  colorsRGBA.push(colorsRGB[i]);
88663
- colorsRGBA.push(colorsRGB[i+1]);
88664
- colorsRGBA.push(colorsRGB[i+2]);
88785
+ colorsRGBA.push(colorsRGB[i + 1]);
88786
+ colorsRGBA.push(colorsRGB[i + 2]);
88665
88787
  colorsRGBA.push(1.0);
88666
88788
  }
88667
88789
  return colorsRGBA;
@@ -88765,6 +88887,8 @@ function load$1(viewer, options, inflatedData, performanceModel) {
88765
88887
  const tileCenter = math.vec3();
88766
88888
  const rtcAABB = math.AABB3();
88767
88889
 
88890
+ const geometryArraysCache = {};
88891
+
88768
88892
  for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {
88769
88893
 
88770
88894
  const lastTileIndex = (numTiles - 1);
@@ -88788,7 +88912,7 @@ function load$1(viewer, options, inflatedData, performanceModel) {
88788
88912
 
88789
88913
  const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);
88790
88914
 
88791
- const geometryCreated = {};
88915
+ const geometryCreatedInTile = {};
88792
88916
 
88793
88917
  // Iterate over each tile's entities
88794
88918
 
@@ -88880,82 +89004,139 @@ function load$1(viewer, options, inflatedData, performanceModel) {
88880
89004
 
88881
89005
  const geometryId = "geometry." + tileIndex + "." + geometryIndex; // These IDs are local to the PerformanceModel
88882
89006
 
88883
- if (!geometryCreated[geometryId]) {
89007
+ let geometryArrays = geometryArraysCache[geometryId];
89008
+
89009
+ if (!geometryArrays) {
89010
+
89011
+ geometryArrays = {
89012
+ batchThisMesh: (!options.reuseGeometries)
89013
+ };
88884
89014
 
88885
89015
  const primitiveType = eachGeometryPrimitiveType[geometryIndex];
88886
89016
 
88887
- let primitiveName;
88888
- let geometryPositions;
88889
- let geometryNormals;
88890
- let geometryColors;
88891
- let geometryIndices;
88892
- let geometryEdgeIndices;
88893
89017
  let geometryValid = false;
88894
89018
 
88895
89019
  switch (primitiveType) {
88896
89020
  case 0:
88897
- primitiveName = "solid";
88898
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
88899
- geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
88900
- geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
88901
- geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
88902
- geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);
89021
+ geometryArrays.primitiveName = "solid";
89022
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89023
+ geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
89024
+ geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89025
+ geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
89026
+ geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);
88903
89027
  break;
88904
89028
  case 1:
88905
- primitiveName = "surface";
88906
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
88907
- geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
88908
- geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
88909
- geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
88910
- geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);
89029
+ geometryArrays.primitiveName = "surface";
89030
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89031
+ geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
89032
+ geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89033
+ geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
89034
+ geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);
88911
89035
  break;
88912
89036
  case 2:
88913
- primitiveName = "points";
88914
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
88915
- geometryColors = convertColorsRGBToRGBA(colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]));
88916
- geometryValid = (geometryPositions.length > 0);
89037
+ geometryArrays.primitiveName = "points";
89038
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89039
+ geometryArrays.geometryColors = convertColorsRGBToRGBA(colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]));
89040
+ geometryValid = (geometryArrays.geometryPositions.length > 0);
88917
89041
  break;
88918
89042
  case 3:
88919
- primitiveName = "lines";
88920
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
88921
- geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
88922
- geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);
89043
+ geometryArrays.primitiveName = "lines";
89044
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89045
+ geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89046
+ geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);
88923
89047
  break;
88924
89048
  default:
88925
89049
  continue;
88926
89050
  }
88927
89051
 
88928
- if (geometryValid) {
88929
-
88930
- performanceModel.createGeometry({
88931
- id: geometryId,
88932
- origin: tileCenter,
88933
- primitive: primitiveName,
88934
- positions: geometryPositions,
88935
- normals: geometryNormals,
88936
- colorsCompressed: geometryColors,
88937
- indices: geometryIndices,
88938
- edgeIndices: geometryEdgeIndices,
88939
- positionsDecodeMatrix: reusedGeometriesDecodeMatrix
88940
- });
89052
+ if (!geometryValid) {
89053
+ geometryArrays = null;
89054
+ }
88941
89055
 
88942
- geometryCreated[geometryId] = true;
89056
+ if (geometryArrays) {
89057
+ if (geometryArrays.geometryPositions.length > 1000) ;
89058
+ if (geometryArrays.batchThisMesh) {
89059
+ geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);
89060
+ const geometryPositions = geometryArrays.geometryPositions;
89061
+ const decompressedPositions = geometryArrays.decompressedPositions;
89062
+ for (let i = 0, len = geometryPositions.length; i < len; i += 3) {
89063
+ decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];
89064
+ decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];
89065
+ decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];
89066
+ }
89067
+ geometryArrays.geometryPositions = null;
89068
+ geometryArraysCache[geometryId] = geometryArrays;
89069
+ }
88943
89070
  }
88944
89071
  }
88945
89072
 
88946
- if (geometryCreated[geometryId]) {
89073
+ if (geometryArrays) {
89074
+
89075
+ if (geometryArrays.batchThisMesh) {
89076
+
89077
+ const decompressedPositions = geometryArrays.decompressedPositions;
89078
+ const positions = new Uint16Array(decompressedPositions.length);
89079
+ for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {
89080
+ tempVec4a$3[0] = decompressedPositions[i + 0];
89081
+ tempVec4a$3[1] = decompressedPositions[i + 1];
89082
+ tempVec4a$3[2] = decompressedPositions[i + 2];
89083
+ tempVec4a$3[3] = 1;
89084
+ math.transformVec4(meshMatrix, tempVec4a$3, tempVec4b$3);
89085
+ geometryCompressionUtils.compressPosition(tempVec4b$3, rtcAABB, tempVec4a$3);
89086
+ positions[i + 0] = tempVec4a$3[0];
89087
+ positions[i + 1] = tempVec4a$3[1];
89088
+ positions[i + 2] = tempVec4a$3[2];
89089
+ }
88947
89090
 
88948
- performanceModel.createMesh(utils.apply(meshDefaults, {
88949
- id: meshId,
88950
- geometryId: geometryId,
88951
- matrix: meshMatrix,
88952
- color: meshColor,
88953
- metallic: meshMetallic,
88954
- roughness: meshRoughness,
88955
- opacity: meshOpacity
88956
- }));
89091
+ performanceModel.createMesh(utils.apply(meshDefaults, {
89092
+ id: meshId,
89093
+ origin: tileCenter,
89094
+ primitive: geometryArrays.primitiveName,
89095
+ positions: positions,
89096
+ normals: geometryArrays.geometryNormals,
89097
+ colorsCompressed: geometryArrays.geometryColors,
89098
+ indices: geometryArrays.geometryIndices,
89099
+ edgeIndices: geometryArrays.geometryEdgeIndices,
89100
+ positionsDecodeMatrix: tileDecodeMatrix,
89101
+ color: meshColor,
89102
+ metallic: meshMetallic,
89103
+ roughness: meshRoughness,
89104
+ opacity: meshOpacity
89105
+ }));
89106
+
89107
+ meshIds.push(meshId);
88957
89108
 
88958
- meshIds.push(meshId);
89109
+ } else {
89110
+
89111
+ if (!geometryCreatedInTile[geometryId]) {
89112
+
89113
+ performanceModel.createGeometry({
89114
+ id: geometryId,
89115
+ origin: tileCenter,
89116
+ primitive: geometryArrays.primitiveName,
89117
+ positions: geometryArrays.geometryPositions,
89118
+ normals: geometryArrays.geometryNormals,
89119
+ colorsCompressed: geometryArrays.geometryColors,
89120
+ indices: geometryArrays.geometryIndices,
89121
+ edgeIndices: geometryArrays.geometryEdgeIndices,
89122
+ positionsDecodeMatrix: reusedGeometriesDecodeMatrix
89123
+ });
89124
+
89125
+ geometryCreatedInTile[geometryId] = true;
89126
+ }
89127
+
89128
+ performanceModel.createMesh(utils.apply(meshDefaults, {
89129
+ id: meshId,
89130
+ geometryId: geometryId,
89131
+ matrix: meshMatrix,
89132
+ color: meshColor,
89133
+ metallic: meshMetallic,
89134
+ roughness: meshRoughness,
89135
+ opacity: meshOpacity
89136
+ }));
89137
+
89138
+ meshIds.push(meshId);
89139
+ }
88959
89140
  }
88960
89141
 
88961
89142
  } else {
@@ -89059,6 +89240,9 @@ if (!pako.inflate) { // See https://github.com/nodeca/pako/issues/97
89059
89240
  pako = pako.default;
89060
89241
  }
89061
89242
 
89243
+ const tempVec4a$2 = math.vec4();
89244
+ const tempVec4b$2 = math.vec4();
89245
+
89062
89246
  function extract(elements) {
89063
89247
 
89064
89248
  return {
@@ -89223,6 +89407,8 @@ function load(viewer, options, inflatedData, performanceModel) {
89223
89407
  const tileCenter = math.vec3();
89224
89408
  const rtcAABB = math.AABB3();
89225
89409
 
89410
+ const geometryArraysCache = {};
89411
+
89226
89412
  for (let tileIndex = 0; tileIndex < numTiles; tileIndex++) {
89227
89413
 
89228
89414
  const lastTileIndex = (numTiles - 1);
@@ -89246,7 +89432,7 @@ function load(viewer, options, inflatedData, performanceModel) {
89246
89432
 
89247
89433
  const tileDecodeMatrix = geometryCompressionUtils.createPositionsDecodeMatrix(rtcAABB);
89248
89434
 
89249
- const geometryCreated = {};
89435
+ const geometryCreatedInTile = {};
89250
89436
 
89251
89437
  // Iterate over each tile's entities
89252
89438
 
@@ -89336,82 +89522,136 @@ function load(viewer, options, inflatedData, performanceModel) {
89336
89522
 
89337
89523
  const geometryId = "geometry." + tileIndex + "." + geometryIndex; // These IDs are local to the PerformanceModel
89338
89524
 
89339
- if (!geometryCreated[geometryId]) {
89525
+ let geometryArrays = geometryArraysCache[geometryId];
89340
89526
 
89527
+ if (!geometryArrays) {
89528
+ geometryArrays = {
89529
+ batchThisMesh: (!options.reuseGeometries)
89530
+ };
89341
89531
  const primitiveType = eachGeometryPrimitiveType[geometryIndex];
89342
-
89343
- let primitiveName;
89344
- let geometryPositions;
89345
- let geometryNormals;
89346
- let geometryColors;
89347
- let geometryIndices;
89348
- let geometryEdgeIndices;
89349
89532
  let geometryValid = false;
89350
-
89351
89533
  switch (primitiveType) {
89352
89534
  case 0:
89353
- primitiveName = "solid";
89354
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89355
- geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
89356
- geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89357
- geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
89358
- geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);
89535
+ geometryArrays.primitiveName = "solid";
89536
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89537
+ geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
89538
+ geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89539
+ geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
89540
+ geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);
89359
89541
  break;
89360
89542
  case 1:
89361
- primitiveName = "surface";
89362
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89363
- geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
89364
- geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89365
- geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
89366
- geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);
89543
+ geometryArrays.primitiveName = "surface";
89544
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89545
+ geometryArrays.geometryNormals = normals.subarray(eachGeometryNormalsPortion [geometryIndex], atLastGeometry ? normals.length : eachGeometryNormalsPortion [geometryIndex + 1]);
89546
+ geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89547
+ geometryArrays.geometryEdgeIndices = edgeIndices.subarray(eachGeometryEdgeIndicesPortion [geometryIndex], atLastGeometry ? edgeIndices.length : eachGeometryEdgeIndicesPortion [geometryIndex + 1]);
89548
+ geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);
89367
89549
  break;
89368
89550
  case 2:
89369
- primitiveName = "points";
89370
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89371
- geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);
89372
- geometryValid = (geometryPositions.length > 0);
89551
+ geometryArrays.primitiveName = "points";
89552
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89553
+ geometryArrays.geometryColors = colors.subarray(eachGeometryColorsPortion [geometryIndex], atLastGeometry ? colors.length : eachGeometryColorsPortion [geometryIndex + 1]);
89554
+ geometryValid = (geometryArrays.geometryPositions.length > 0);
89373
89555
  break;
89374
89556
  case 3:
89375
- primitiveName = "lines";
89376
- geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89377
- geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89378
- geometryValid = (geometryPositions.length > 0 && geometryIndices.length > 0);
89557
+ geometryArrays.primitiveName = "lines";
89558
+ geometryArrays.geometryPositions = positions.subarray(eachGeometryPositionsPortion [geometryIndex], atLastGeometry ? positions.length : eachGeometryPositionsPortion [geometryIndex + 1]);
89559
+ geometryArrays.geometryIndices = indices.subarray(eachGeometryIndicesPortion [geometryIndex], atLastGeometry ? indices.length : eachGeometryIndicesPortion [geometryIndex + 1]);
89560
+ geometryValid = (geometryArrays.geometryPositions.length > 0 && geometryArrays.geometryIndices.length > 0);
89379
89561
  break;
89380
89562
  default:
89381
89563
  continue;
89382
89564
  }
89383
89565
 
89384
- if (geometryValid) {
89385
-
89386
- performanceModel.createGeometry({
89387
- id: geometryId,
89388
- origin: tileCenter,
89389
- primitive: primitiveName,
89390
- positions: geometryPositions,
89391
- normals: geometryNormals,
89392
- colorsCompressed: geometryColors,
89393
- indices: geometryIndices,
89394
- edgeIndices: geometryEdgeIndices,
89395
- positionsDecodeMatrix: reusedGeometriesDecodeMatrix
89396
- });
89566
+ if (!geometryValid) {
89567
+ geometryArrays = null;
89568
+ }
89397
89569
 
89398
- geometryCreated[geometryId] = true;
89570
+ if (geometryArrays) {
89571
+ if (geometryArrays.geometryPositions.length > 1000) ;
89572
+ if (geometryArrays.batchThisMesh) {
89573
+ geometryArrays.decompressedPositions = new Float32Array(geometryArrays.geometryPositions.length);
89574
+ const geometryPositions = geometryArrays.geometryPositions;
89575
+ const decompressedPositions = geometryArrays.decompressedPositions;
89576
+ for (let i = 0, len = geometryPositions.length; i < len; i += 3) {
89577
+ decompressedPositions[i + 0] = geometryPositions[i + 0] * reusedGeometriesDecodeMatrix[0] + reusedGeometriesDecodeMatrix[12];
89578
+ decompressedPositions[i + 1] = geometryPositions[i + 1] * reusedGeometriesDecodeMatrix[5] + reusedGeometriesDecodeMatrix[13];
89579
+ decompressedPositions[i + 2] = geometryPositions[i + 2] * reusedGeometriesDecodeMatrix[10] + reusedGeometriesDecodeMatrix[14];
89580
+ }
89581
+ geometryArrays.geometryPositions = null;
89582
+ geometryArraysCache[geometryId] = geometryArrays;
89583
+ }
89399
89584
  }
89400
89585
  }
89401
89586
 
89402
- if (geometryCreated[geometryId]) {
89587
+ if (geometryArrays) {
89403
89588
 
89404
- performanceModel.createMesh(utils.apply(meshDefaults, {
89405
- id: meshId,
89406
- geometryId: geometryId,
89407
- matrix: meshMatrix,
89408
- color: meshColor,
89409
- metallic: meshMetallic,
89410
- roughness: meshRoughness,
89411
- opacity: meshOpacity
89412
- }));
89589
+ if (geometryArrays.batchThisMesh) {
89413
89590
 
89414
- meshIds.push(meshId);
89591
+ const decompressedPositions = geometryArrays.decompressedPositions;
89592
+ const transformedAndRecompressedPositions = new Uint16Array(decompressedPositions.length);
89593
+
89594
+ for (let i = 0, len = decompressedPositions.length; i < len; i += 3) {
89595
+ tempVec4a$2[0] = decompressedPositions[i + 0];
89596
+ tempVec4a$2[1] = decompressedPositions[i + 1];
89597
+ tempVec4a$2[2] = decompressedPositions[i + 2];
89598
+ tempVec4a$2[3] = 1;
89599
+ math.transformVec4(meshMatrix, tempVec4a$2, tempVec4b$2);
89600
+ geometryCompressionUtils.compressPosition(tempVec4b$2, rtcAABB, tempVec4a$2);
89601
+ transformedAndRecompressedPositions[i + 0] = tempVec4a$2[0];
89602
+ transformedAndRecompressedPositions[i + 1] = tempVec4a$2[1];
89603
+ transformedAndRecompressedPositions[i + 2] = tempVec4a$2[2];
89604
+ }
89605
+
89606
+ performanceModel.createMesh(utils.apply(meshDefaults, {
89607
+ id: meshId,
89608
+ origin: tileCenter,
89609
+ primitive: geometryArrays.primitiveName,
89610
+ positions: transformedAndRecompressedPositions,
89611
+ normals: geometryArrays.geometryNormals,
89612
+ colorsCompressed: geometryArrays.geometryColors,
89613
+ indices: geometryArrays.geometryIndices,
89614
+ edgeIndices: geometryArrays.geometryEdgeIndices,
89615
+ positionsDecodeMatrix: tileDecodeMatrix,
89616
+ color: meshColor,
89617
+ metallic: meshMetallic,
89618
+ roughness: meshRoughness,
89619
+ opacity: meshOpacity
89620
+ }));
89621
+
89622
+ meshIds.push(meshId);
89623
+
89624
+ } else {
89625
+
89626
+ if (!geometryCreatedInTile[geometryId]) {
89627
+
89628
+ performanceModel.createGeometry({
89629
+ id: geometryId,
89630
+ origin: tileCenter,
89631
+ primitive: geometryArrays.primitiveName,
89632
+ positions: geometryArrays.geometryPositions,
89633
+ normals: geometryArrays.geometryNormals,
89634
+ colorsCompressed: geometryArrays.geometryColors,
89635
+ indices: geometryArrays.geometryIndices,
89636
+ edgeIndices: geometryArrays.geometryEdgeIndices,
89637
+ positionsDecodeMatrix: reusedGeometriesDecodeMatrix
89638
+ });
89639
+
89640
+ geometryCreatedInTile[geometryId] = true;
89641
+ }
89642
+
89643
+ performanceModel.createMesh(utils.apply(meshDefaults, {
89644
+ id: meshId,
89645
+ geometryId: geometryId,
89646
+ matrix: meshMatrix,
89647
+ color: meshColor,
89648
+ metallic: meshMetallic,
89649
+ roughness: meshRoughness,
89650
+ opacity: meshOpacity
89651
+ }));
89652
+
89653
+ meshIds.push(meshId);
89654
+ }
89415
89655
  }
89416
89656
 
89417
89657
  } else {
@@ -89883,6 +90123,10 @@ class XKTLoaderPlugin extends Plugin {
89883
90123
  * @param {String[]} [cfg.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
89884
90124
  * @param {String[]} [cfg.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
89885
90125
  * @param {Boolean} [cfg.excludeUnclassifiedObjects=false] When loading metadata and this is ````true````, will only load {@link Entity}s that have {@link MetaObject}s (that are not excluded). This is useful when we don't want Entitys in the Scene that are not represented within IFC navigation components, such as {@link TreeViewPlugin}.
90126
+ * @param {Boolean} [cfg.reuseGeometries=true] Indicates whether to enable geometry reuse (````true```` by default) or whether to internally expand
90127
+ * all geometry instances into batches (````false````), and not use instancing to render them. Setting this ````false```` can significantly
90128
+ * improve Viewer performance for models that have a lot of geometry reuse, but may also increase the amount of
90129
+ * browser and GPU memory they require. See [#769](https://github.com/xeokit/xeokit-sdk/issues/769) for more info.
89886
90130
  * @param {Number} [cfg.maxGeometryBatchSize=50000000] Maximum geometry batch size, as number of vertices. This is optionally supplied
89887
90131
  * to limit the size of the batched geometry arrays that {@link PerformanceModel} internally creates for batched geometries.
89888
90132
  * A low value means less heap allocation/de-allocation while loading batched geometries, but more draw calls and
@@ -89900,6 +90144,7 @@ class XKTLoaderPlugin extends Plugin {
89900
90144
  this.includeTypes = cfg.includeTypes;
89901
90145
  this.excludeTypes = cfg.excludeTypes;
89902
90146
  this.excludeUnclassifiedObjects = cfg.excludeUnclassifiedObjects;
90147
+ this.reuseGeometries = cfg.reuseGeometries;
89903
90148
  }
89904
90149
 
89905
90150
  /**
@@ -90070,6 +90315,36 @@ class XKTLoaderPlugin extends Plugin {
90070
90315
  this._globalizeObjectIds = !!value;
90071
90316
  }
90072
90317
 
90318
+ /**
90319
+ * Gets whether XKTLoaderPlugin enables geometry reuse when loading models.
90320
+ *
90321
+ * Default value is ````true````.
90322
+ *
90323
+ * @type {Boolean}
90324
+ */
90325
+ get reuseGeometries() {
90326
+ return this._reuseGeometries;
90327
+ }
90328
+
90329
+ /**
90330
+ * Sets whether XKTLoaderPlugin enables geometry reuse when loading models.
90331
+ *
90332
+ * Default value is ````true````.
90333
+ *
90334
+ * Geometry reuse saves memory, but can impact Viewer performance when there are many reused geometries. For
90335
+ * this reason, we can set this ````false```` to disable geometry reuse for models loaded by this XKTLoaderPlugin
90336
+ * (which will then "expand" the geometry instances into batches instead).
90337
+ *
90338
+ * The result will be be less WebGL draw calls (which are expensive), at the cost of increased memory footprint.
90339
+ *
90340
+ * See [#769](https://github.com/xeokit/xeokit-sdk/issues/769) for more info.
90341
+ *
90342
+ * @type {Boolean}
90343
+ */
90344
+ set reuseGeometries(value) {
90345
+ this._reuseGeometries = value !== false;
90346
+ }
90347
+
90073
90348
  /**
90074
90349
  * Loads an ````.xkt```` model into this XKTLoaderPlugin's {@link Viewer}.
90075
90350
  *
@@ -90102,6 +90377,10 @@ class XKTLoaderPlugin extends Plugin {
90102
90377
  * Viewer will hide backfaces on watertight meshes, show backfaces on open meshes, and always show backfaces on meshes when we slice them open with {@link SectionPlane}s.
90103
90378
  * @param {Boolean} [params.excludeUnclassifiedObjects=false] When loading metadata and this is ````true````, will only load {@link Entity}s that have {@link MetaObject}s (that are not excluded). This is useful when we don't want Entitys in the Scene that are not represented within IFC navigation components, such as {@link TreeViewPlugin}.
90104
90379
  * @param {Boolean} [params.globalizeObjectIds=false] Indicates whether to globalize each {@link Entity#id} and {@link MetaObject#id}, in case you need to prevent ID clashes with other models. See {@link XKTLoaderPlugin#globalizeObjectIds} for more info.
90380
+ * @param {Boolean} [params.reuseGeometries=true] Indicates whether to enable geometry reuse (````true```` by default) or whether to expand
90381
+ * all geometry instances into batches (````false````), and not use instancing to render them. Setting this ````false```` can significantly
90382
+ * improve Viewer performance for models that have excessive geometry reuse, but may also increases the amount of
90383
+ * browser and GPU memory used by the model. See [#769](https://github.com/xeokit/xeokit-sdk/issues/769) for more info.
90105
90384
  * @returns {Entity} Entity representing the model, which will have {@link Entity#isModel} set ````true```` and will be registered by {@link Entity#id} in {@link Scene#models}.
90106
90385
  */
90107
90386
  load(params = {}) {
@@ -90129,6 +90408,8 @@ class XKTLoaderPlugin extends Plugin {
90129
90408
  const excludeTypes = params.excludeTypes || this._excludeTypes;
90130
90409
  const objectDefaults = params.objectDefaults || this._objectDefaults;
90131
90410
 
90411
+ options.reuseGeometries = (params.reuseGeometries !== null && params.reuseGeometries !== undefined ) ? params.reuseGeometries : (this._reuseGeometries !== false);
90412
+
90132
90413
  if (includeTypes) {
90133
90414
  options.includeTypesMap = {};
90134
90415
  for (let i = 0, len = includeTypes.length; i < len; i++) {