@xeokit/xeokit-sdk 2.4.2-beta-37 → 2.4.2-beta-39

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 (22) hide show
  1. package/dist/xeokit-sdk.cjs.js +145 -35
  2. package/dist/xeokit-sdk.es.js +145 -35
  3. package/dist/xeokit-sdk.es5.js +262 -249
  4. package/dist/xeokit-sdk.min.cjs.js +2 -2
  5. package/dist/xeokit-sdk.min.es.js +2 -2
  6. package/dist/xeokit-sdk.min.es5.js +3 -3
  7. package/package.json +1 -1
  8. package/src/viewer/scene/model/SceneModel.js +1 -1
  9. package/src/viewer/scene/model/SceneModelMesh.js +2 -0
  10. package/src/viewer/scene/model/dtx/triangles/TrianglesDataTextureLayer.js +24 -9
  11. package/src/viewer/scene/model/dtx/triangles/renderers/TrianglesDataTextureSnapDepthBufInitRenderer.js +1 -1
  12. package/src/viewer/scene/model/dtx/triangles/renderers/TrianglesDataTextureSnapDepthRenderer.js +1 -1
  13. package/src/viewer/scene/model/vbo/linesBatching/LinesBatchingLayer.js +19 -3
  14. package/src/viewer/scene/model/vbo/linesInstancing/LinesInstancingLayer.js +19 -1
  15. package/src/viewer/scene/model/vbo/pointsBatching/PointsBatchingLayer.js +21 -6
  16. package/src/viewer/scene/model/vbo/pointsInstancing/PointsInstancingLayer.js +17 -2
  17. package/src/viewer/scene/model/vbo/snapBatching/SnapBatchingDepthBufInitRenderer.js +1 -1
  18. package/src/viewer/scene/model/vbo/snapBatching/SnapBatchingDepthRenderer.js +1 -1
  19. package/src/viewer/scene/model/vbo/snapInstancing/SnapInstancingDepthBufInitRenderer.js +1 -1
  20. package/src/viewer/scene/model/vbo/snapInstancing/SnapInstancingDepthRenderer.js +1 -1
  21. package/src/viewer/scene/model/vbo/trianglesBatching/TrianglesBatchingLayer.js +18 -8
  22. package/src/viewer/scene/model/vbo/trianglesInstancing/TrianglesInstancingLayer.js +18 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xeokit/xeokit-sdk",
3
- "version": "2.4.2-beta-37",
3
+ "version": "2.4.2-beta-39",
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",
@@ -3072,7 +3072,7 @@ export class SceneModel extends Component {
3072
3072
  if (cfg.transform) {
3073
3073
  cfg.meshMatrix = cfg.transform.worldMatrix;
3074
3074
  }
3075
- mesh.portionId = mesh.layer.createPortion(cfg);
3075
+ mesh.portionId = mesh.layer.createPortion(mesh, cfg);
3076
3076
  this._meshes[cfg.id] = mesh;
3077
3077
  this._meshList.push(mesh);
3078
3078
  return mesh;
@@ -120,6 +120,7 @@ export class SceneModelMesh {
120
120
 
121
121
  _sceneModelDirty() {
122
122
  this._aabbWorldDirty = true;
123
+ this.layer.aabbDirty = true;
123
124
  }
124
125
 
125
126
  _transformDirty() {
@@ -129,6 +130,7 @@ export class SceneModelMesh {
129
130
  this._matrixUpdateScheduled = true;
130
131
  }
131
132
  this._aabbWorldDirty = true;
133
+ this.layer.aabbDirty = true;
132
134
  if (this.entity) {
133
135
  this.entity._transformDirty();
134
136
  }
@@ -2,7 +2,6 @@ import {ENTITY_FLAGS} from '../../ENTITY_FLAGS.js';
2
2
  import {RENDER_PASSES} from '../../RENDER_PASSES.js';
3
3
  import {math} from "../../../math/math.js";
4
4
  import {RenderState} from "../../../webgl/RenderState.js";
5
- import {geometryCompressionUtils} from "../../../math/geometryCompressionUtils.js";
6
5
  import {getDataTextureRenderers} from "./TrianglesDataTextureRenderers.js";
7
6
  import {TrianglesDataTextureBuffer} from "./TrianglesDataTextureBuffer.js";
8
7
  import {DataTextureState} from "./DataTextureState.js"
@@ -110,10 +109,13 @@ export class TrianglesDataTextureLayer {
110
109
 
111
110
  this._bucketGeometries = {};
112
111
 
112
+ this._meshes = [];
113
+
113
114
  /**
114
115
  * The axis-aligned World-space boundary of this TrianglesDataTextureLayer's positions.
115
116
  */
116
- this.aabb = math.collapseAABB3();
117
+ this._aabb = math.collapseAABB3();
118
+ this.aabbDirty = true;
117
119
 
118
120
  /**
119
121
  * The number of updates in the current frame;
@@ -123,6 +125,17 @@ export class TrianglesDataTextureLayer {
123
125
  this._finalized = false;
124
126
  }
125
127
 
128
+ get aabb() {
129
+ if (this.aabbDirty) {
130
+ math.collapseAABB3(this._aabb);
131
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
132
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
133
+ }
134
+ this.aabbDirty = false;
135
+ }
136
+ return this._aabb;
137
+ }
138
+
126
139
  /**
127
140
  * Returns whether the ```TrianglesDataTextureLayer``` has room for more portions.
128
141
  *
@@ -167,6 +180,7 @@ export class TrianglesDataTextureLayer {
167
180
  *
168
181
  * Gives the portion the specified geometry, color and matrix.
169
182
  *
183
+ * @param mesh The SceneModelMesh that owns the portion
170
184
  * @param portionCfg.positionsCompressed Flat float Local-space positionsCompressed array.
171
185
  * @param [portionCfg.normals] Flat float normals array.
172
186
  * @param [portionCfg.colors] Flat float colors array.
@@ -181,12 +195,12 @@ export class TrianglesDataTextureLayer {
181
195
  * @param portionCfg.pickColor Quantized pick color
182
196
  * @returns {number} Portion ID
183
197
  */
184
- createPortion(portionCfg) {
198
+ createPortion(mesh, portionCfg) {
185
199
  if (this._finalized) {
186
200
  throw "Already finalized";
187
201
  }
188
202
  const subPortionIds = [];
189
- // const portionAABB = portionCfg.worldAABB;
203
+ // const portionAABB = portionCfg.worldAABB;
190
204
  portionCfg.buckets.forEach((bucket, bucketIndex) => {
191
205
  const bucketGeometryId = portionCfg.geometryId !== undefined && portionCfg.geometryId !== null
192
206
  ? `${portionCfg.geometryId}#${bucketIndex}`
@@ -196,7 +210,7 @@ export class TrianglesDataTextureLayer {
196
210
  bucketGeometry = this._createBucketGeometry(portionCfg, bucket);
197
211
  this._bucketGeometries[bucketGeometryId] = bucketGeometry;
198
212
  }
199
- // const subPortionAABB = math.collapseAABB3(tempAABB3b);
213
+ // const subPortionAABB = math.collapseAABB3(tempAABB3b);
200
214
  const subPortionId = this._createSubPortion(portionCfg, bucketGeometry, bucket);
201
215
  //math.expandAABB3(portionAABB, subPortionAABB);
202
216
  subPortionIds.push(subPortionId);
@@ -214,6 +228,7 @@ export class TrianglesDataTextureLayer {
214
228
  const portionId = this._portionToSubPortionsMap.length;
215
229
  this._portionToSubPortionsMap.push(subPortionIds);
216
230
  this.model.numPortions++;
231
+ this._meshes.push(mesh);
217
232
  return portionId;
218
233
  }
219
234
 
@@ -318,7 +333,7 @@ export class TrianglesDataTextureLayer {
318
333
  numEdges,
319
334
  indicesBase,
320
335
  edgeIndicesBase,
321
- // aabb,
336
+ // aabb,
322
337
  obb: null // Lazy-created in _createSubPortion if needed
323
338
  };
324
339
 
@@ -498,7 +513,7 @@ export class TrianglesDataTextureLayer {
498
513
  textureState.texturePerVertexIdCoordinates = this._dataTextureGenerator.generateTextureForPositions(
499
514
  gl,
500
515
  buffer.positionsCompressed,
501
- buffer.lenPositionsCompressed );
516
+ buffer.lenPositionsCompressed);
502
517
 
503
518
  textureState.texturePerPolygonIdPortionIds8Bits = this._dataTextureGenerator.generateTextureForPackedPortionIds(
504
519
  gl,
@@ -1079,7 +1094,7 @@ export class TrianglesDataTextureLayer {
1079
1094
  const textureState = this._dataTextureState;
1080
1095
  const gl = this.model.scene.canvas.gl;
1081
1096
  tempMat4a.set(matrix);
1082
- textureState.texturePerObjectInstanceMatrices._textureData.set(tempMat4a, subPortionId*16);
1097
+ textureState.texturePerObjectInstanceMatrices._textureData.set(tempMat4a, subPortionId * 16);
1083
1098
  if (this._deferredSetFlagsActive) {
1084
1099
  this._deferredSetFlagsDirty = true;
1085
1100
  return;
@@ -1102,7 +1117,7 @@ export class TrianglesDataTextureLayer {
1102
1117
  );
1103
1118
  // gl.bindTexture (gl.TEXTURE_2D, null);
1104
1119
  }
1105
-
1120
+
1106
1121
  // ---------------------- COLOR RENDERING -----------------------------------
1107
1122
 
1108
1123
  drawColorOpaque(renderFlags, frameCtx) {
@@ -48,7 +48,7 @@ export class TrianglesDataTextureSnapDepthBufInitRenderer {
48
48
  const textureState = state.textureState;
49
49
  const origin = dataTextureLayer._state.origin;
50
50
  const {position, rotationMatrix, rotationMatrixConjugate} = model;
51
- const aabb = dataTextureLayer.aabb;
51
+ const aabb = dataTextureLayer.aabb; // Per-layer AABB for best RTC accuracy
52
52
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
53
53
 
54
54
  const coordinateScaler = tempVec3a;
@@ -52,7 +52,7 @@ export class TrianglesDataTextureSnapDepthRenderer {
52
52
  const textureState = state.textureState;
53
53
  const origin = dataTextureLayer._state.origin;
54
54
  const {position, rotationMatrix, rotationMatrixConjugate} = model;
55
- const aabb = dataTextureLayer.aabb;
55
+ const aabb = dataTextureLayer.aabb; // Per-layer AABB for best RTC accuracy
56
56
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
57
57
 
58
58
  const coordinateScaler = tempVec3a;
@@ -4,7 +4,6 @@ import {RENDER_PASSES} from '../../RENDER_PASSES.js';
4
4
  import {math} from "../../../math/math.js";
5
5
  import {RenderState} from "../../../webgl/RenderState.js";
6
6
  import {ArrayBuf} from "../../../webgl/ArrayBuf.js";
7
- import {geometryCompressionUtils} from "../../../math/geometryCompressionUtils.js";
8
7
  import {getBatchingRenderers} from "./LinesBatchingRenderers.js";
9
8
  import {LinesBatchingBuffer} from "./LinesBatchingBuffer.js";
10
9
  import {quantizePositions} from "../../compression.js";
@@ -65,9 +64,12 @@ class LinesBatchingLayer {
65
64
 
66
65
  this._modelAABB = math.collapseAABB3(); // Model-space AABB
67
66
  this._portions = [];
68
-
67
+ this._meshes = [];
69
68
  this._numVerts = 0;
70
69
 
70
+ this._aabb = math.collapseAABB3();
71
+ this.aabbDirty = true;
72
+
71
73
  this._finalized = false;
72
74
 
73
75
  if (cfg.positionsDecodeMatrix) {
@@ -88,6 +90,17 @@ class LinesBatchingLayer {
88
90
  this.aabb = math.collapseAABB3();
89
91
  }
90
92
 
93
+ get aabb() {
94
+ if (this.aabbDirty) {
95
+ math.collapseAABB3(this._aabb);
96
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
97
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
98
+ }
99
+ this.aabbDirty = false;
100
+ }
101
+ return this._aabb;
102
+ }
103
+
91
104
  /**
92
105
  * Tests if there is room for another portion in this LinesBatchingLayer.
93
106
  *
@@ -107,6 +120,7 @@ class LinesBatchingLayer {
107
120
  *
108
121
  * Gives the portion the specified geometry, color and matrix.
109
122
  *
123
+ * @param mesh The SceneModelMesh that owns the portion
110
124
  * @param cfg.positions Flat float Local-space positions array.
111
125
  * @param cfg.positionsCompressed Flat quantized positions array - decompressed with TrianglesBatchingLayer positionsDecodeMatrix
112
126
  * @param cfg.indices Flat int indices array.
@@ -117,7 +131,7 @@ class LinesBatchingLayer {
117
131
  * @param cfg.pickColor Quantized pick color
118
132
  * @returns {number} Portion ID
119
133
  */
120
- createPortion(cfg) {
134
+ createPortion(mesh, cfg) {
121
135
 
122
136
  if (this._finalized) {
123
137
  throw "Already finalized";
@@ -194,6 +208,8 @@ class LinesBatchingLayer {
194
208
 
195
209
  this._numVerts += numVerts;
196
210
 
211
+ this._meshes.push(mesh);
212
+
197
213
  return portionId;
198
214
  }
199
215
 
@@ -100,6 +100,10 @@ class LinesInstancingLayer {
100
100
  this._modelMatrixCol2 = [];
101
101
 
102
102
  this._portions = [];
103
+ this._meshes = [];
104
+
105
+ this._aabb = math.collapseAABB3();
106
+ this.aabbDirty = true;
103
107
 
104
108
  if (cfg.origin) {
105
109
  this._state.origin = math.vec3(cfg.origin);
@@ -108,6 +112,17 @@ class LinesInstancingLayer {
108
112
  this._finalized = false;
109
113
  }
110
114
 
115
+ get aabb() {
116
+ if (this.aabbDirty) {
117
+ math.collapseAABB3(this._aabb);
118
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
119
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
120
+ }
121
+ this.aabbDirty = false;
122
+ }
123
+ return this._aabb;
124
+ }
125
+
111
126
  /**
112
127
  * Creates a new portion within this InstancingLayer, returns the new portion ID.
113
128
  *
@@ -115,13 +130,14 @@ class LinesInstancingLayer {
115
130
  *
116
131
  * Gives the portion the specified color and matrix.
117
132
  *
133
+ * @param mesh The SceneModelMesh that owns the portion
118
134
  * @param cfg Portion params
119
135
  * @param cfg.color Color [0..255,0..255,0..255]
120
136
  * @param cfg.opacity Opacity [0..255].
121
137
  * @param cfg.meshMatrix Flat float 4x4 matrix.
122
138
  * @returns {number} Portion ID.
123
139
  */
124
- createPortion(cfg) {
140
+ createPortion(mesh, cfg) {
125
141
 
126
142
  const color = cfg.color;
127
143
  const opacity = cfg.opacity;
@@ -170,6 +186,8 @@ class LinesInstancingLayer {
170
186
  this._numPortions++;
171
187
  this.model.numPortions++;
172
188
 
189
+ this._meshes.push(mesh);
190
+
173
191
  return portionId;
174
192
  }
175
193
 
@@ -4,7 +4,6 @@ import {RENDER_PASSES} from '../../RENDER_PASSES.js';
4
4
  import {math} from "../../../math/math.js";
5
5
  import {RenderState} from "../../../webgl/RenderState.js";
6
6
  import {ArrayBuf} from "../../../webgl/ArrayBuf.js";
7
- import {geometryCompressionUtils} from "../../../math/geometryCompressionUtils.js";
8
7
  import {getPointsBatchingRenderers} from "./PointsBatchingRenderers.js";
9
8
  import {PointsBatchingBuffer} from "./PointsBatchingBuffer.js";
10
9
  import {quantizePositions} from "../../compression.js";
@@ -77,6 +76,10 @@ class PointsBatchingLayer {
77
76
 
78
77
  this._modelAABB = math.collapseAABB3(); // Model-space AABB
79
78
  this._portions = [];
79
+ this._meshes = [];
80
+
81
+ this._aabb = math.collapseAABB3();
82
+ this.aabbDirty = true;
80
83
 
81
84
  this._finalized = false;
82
85
 
@@ -98,6 +101,17 @@ class PointsBatchingLayer {
98
101
  this.aabb = math.collapseAABB3();
99
102
  }
100
103
 
104
+ get aabb() {
105
+ if (this.aabbDirty) {
106
+ math.collapseAABB3(this._aabb);
107
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
108
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
109
+ }
110
+ this.aabbDirty = false;
111
+ }
112
+ return this._aabb;
113
+ }
114
+
101
115
  /**
102
116
  * Tests if there is room for another portion in this PointsBatchingLayer.
103
117
  *
@@ -116,6 +130,7 @@ class PointsBatchingLayer {
116
130
  *
117
131
  * Gives the portion the specified geometry, color and matrix.
118
132
  *
133
+ * @param mesh The SceneModelMesh that owns the portion
119
134
  * @param cfg.positions Flat float Local-space positions array.
120
135
  * @param cfg.positionsCompressed Flat quantized positions array - decompressed with PointsBatchingLayer positionsDecodeMatrix
121
136
  * @param [cfg.colorsCompressed] Quantized RGB colors [0..255,0..255,0..255,0..255]
@@ -126,7 +141,7 @@ class PointsBatchingLayer {
126
141
  * @param cfg.pickColor Quantized pick color
127
142
  * @returns {number} Portion ID
128
143
  */
129
- createPortion(cfg) {
144
+ createPortion(mesh, cfg) {
130
145
 
131
146
  if (this._finalized) {
132
147
  throw "Already finalized";
@@ -137,7 +152,7 @@ class PointsBatchingLayer {
137
152
  const color = cfg.color;
138
153
  const colorsCompressed = cfg.colorsCompressed;
139
154
  const colors = cfg.colors;
140
- const pickColor = cfg.pickColor;
155
+ const pickColor = cfg.pickColor;
141
156
 
142
157
  const buffer = this._buffer;
143
158
  const positionsIndex = buffer.positions.length;
@@ -226,7 +241,7 @@ class PointsBatchingLayer {
226
241
 
227
242
  this._numPortions++;
228
243
  this.model.numPortions++;
229
-
244
+ this._meshes.push(mesh);
230
245
  return portionId;
231
246
  }
232
247
 
@@ -490,7 +505,7 @@ class PointsBatchingLayer {
490
505
  let colorFlag;
491
506
  if (!visible || culled || xrayed
492
507
  || (highlighted && !this.model.scene.highlightMaterial.glowThrough)
493
- || (selected && !this.model.scene.selectedMaterial.glowThrough) ) {
508
+ || (selected && !this.model.scene.selectedMaterial.glowThrough)) {
494
509
  colorFlag = RENDER_PASSES.NOT_RENDERED;
495
510
  } else {
496
511
  if (transparent) {
@@ -524,7 +539,7 @@ class PointsBatchingLayer {
524
539
  // no edges
525
540
  vertFlag |= pickFlag << 12;
526
541
  vertFlag |= clippableFlag << 16;
527
-
542
+
528
543
  tempArray[i] = vertFlag;
529
544
  }
530
545
 
@@ -97,10 +97,24 @@ class PointsInstancingLayer {
97
97
  this._modelMatrixCol2 = [];
98
98
 
99
99
  this._portions = [];
100
+ this._meshes = [];
101
+ this._aabb = math.collapseAABB3();
102
+ this.aabbDirty = true;
100
103
 
101
104
  this._finalized = false;
102
105
  }
103
106
 
107
+ get aabb() {
108
+ if (this.aabbDirty) {
109
+ math.collapseAABB3(this._aabb);
110
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
111
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
112
+ }
113
+ this.aabbDirty = false;
114
+ }
115
+ return this._aabb;
116
+ }
117
+
104
118
  /**
105
119
  * Creates a new portion within this InstancingLayer, returns the new portion ID.
106
120
  *
@@ -108,13 +122,14 @@ class PointsInstancingLayer {
108
122
  *
109
123
  * Gives the portion the specified color and matrix.
110
124
  *
125
+ * @param mesh The SceneModelMesh that owns the portion
111
126
  * @param cfg Portion params
112
127
  * @param cfg.meshMatrix Flat float 4x4 matrix.
113
128
  * @param [cfg.worldMatrix] Flat float 4x4 matrix.
114
129
  * @param cfg.pickColor Quantized pick color
115
130
  * @returns {number} Portion ID.
116
131
  */
117
- createPortion(cfg) {
132
+ createPortion(mesh, cfg) {
118
133
 
119
134
  const meshMatrix = cfg.meshMatrix;
120
135
  const pickColor = cfg.pickColor;
@@ -158,7 +173,7 @@ class PointsInstancingLayer {
158
173
 
159
174
  this._numPortions++;
160
175
  this.model.numPortions++;
161
-
176
+ this._meshes.push(mesh);
162
177
  return portionId;
163
178
  }
164
179
 
@@ -35,7 +35,7 @@ export class SnapBatchingDepthBufInitRenderer extends VBOSceneModelRenderer {
35
35
  const state = batchingLayer._state;
36
36
  const origin = batchingLayer._state.origin;
37
37
  const {position, rotationMatrix, rotationMatrixConjugate} = model;
38
- const aabb = model.aabb;
38
+ const aabb = batchingLayer.aabb; // Per-layer AABB for best RTC accuracy
39
39
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
40
40
 
41
41
  if (this._vaoCache.has(batchingLayer)) {
@@ -39,7 +39,7 @@ export class SnapBatchingDepthRenderer extends VBOSceneModelRenderer{
39
39
  const state = batchingLayer._state;
40
40
  const origin = batchingLayer._state.origin;
41
41
  const {position, rotationMatrix, rotationMatrixConjugate} = model;
42
- const aabb = model.aabb;
42
+ const aabb = batchingLayer.aabb; // Per-layer AABB for best RTC accuracy
43
43
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
44
44
 
45
45
  if (this._vaoCache.has(batchingLayer)) {
@@ -40,7 +40,7 @@ class SnapInstancingDepthBufInitRenderer extends VBOSceneModelRenderer {
40
40
  const state = instancingLayer._state;
41
41
  const origin = instancingLayer._state.origin;
42
42
  const {position, rotationMatrix, rotationMatrixConjugate} = model;
43
- const aabb = model.aabb;
43
+ const aabb = instancingLayer.aabb; // Per-layer AABB for best RTC accuracy
44
44
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
45
45
 
46
46
  if (this._vaoCache.has(instancingLayer)) {
@@ -40,7 +40,7 @@ class SnapInstancingDepthRenderer extends VBOSceneModelRenderer {
40
40
  const state = instancingLayer._state;
41
41
  const origin = instancingLayer._state.origin;
42
42
  const {position, rotationMatrix, rotationMatrixConjugate} = model;
43
- const aabb = model.aabb;
43
+ const aabb = instancingLayer.aabb; // Per-layer AABB for best RTC accuracy
44
44
  const viewMatrix = frameCtx.pickViewMatrix || camera.viewMatrix;
45
45
 
46
46
  if (this._vaoCache.has(instancingLayer)) {
@@ -106,9 +106,12 @@ class TrianglesBatchingLayer {
106
106
 
107
107
  this._modelAABB = math.collapseAABB3(); // Model-space AABB
108
108
  this._portions = [];
109
-
109
+ this._meshes = [];
110
110
  this._numVerts = 0;
111
111
 
112
+ this._aabb = math.collapseAABB3();
113
+ this.aabbDirty = true;
114
+
112
115
  this._finalized = false;
113
116
 
114
117
  if (cfg.positionsDecodeMatrix) {
@@ -139,6 +142,16 @@ class TrianglesBatchingLayer {
139
142
  this.solid = !!cfg.solid;
140
143
  }
141
144
 
145
+ get aabb() {
146
+ if (this.aabbDirty) {
147
+ math.collapseAABB3(this._aabb);
148
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
149
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
150
+ }
151
+ this.aabbDirty = false;
152
+ }
153
+ }
154
+
142
155
  /**
143
156
  * Tests if there is room for another portion in this TrianglesBatchingLayer.
144
157
  *
@@ -158,6 +171,7 @@ class TrianglesBatchingLayer {
158
171
  *
159
172
  * Gives the portion the specified geometry, color and matrix.
160
173
  *
174
+ * @param mesh The SceneModelMesh that owns the portion
161
175
  * @param cfg.positions Flat float Local-space positions array.
162
176
  * @param cfg.positionsCompressed Flat quantized positions array - decompressed with TrianglesBatchingLayer positionsDecodeMatrix
163
177
  * @param [cfg.normals] Flat float normals array.
@@ -176,7 +190,7 @@ class TrianglesBatchingLayer {
176
190
  * @param cfg.pickColor Quantized pick color
177
191
  * @returns {number} Portion ID
178
192
  */
179
- createPortion(cfg) {
193
+ createPortion(mesh, cfg) {
180
194
 
181
195
  if (this._finalized) {
182
196
  throw "Already finalized";
@@ -215,8 +229,7 @@ class TrianglesBatchingLayer {
215
229
  for (let i = 0, len = positionsCompressed.length; i < len; i++) {
216
230
  buffer.positions.push(positionsCompressed[i]);
217
231
  }
218
- }
219
- else {
232
+ } else {
220
233
  if (!positions) {
221
234
  throw "positions expected";
222
235
  }
@@ -333,13 +346,10 @@ class TrianglesBatchingLayer {
333
346
  }
334
347
 
335
348
  this._portions.push(portion);
336
-
337
349
  this._numPortions++;
338
-
339
350
  this.model.numPortions++;
340
-
341
351
  this._numVerts += portion.numVerts;
342
-
352
+ this._meshes.push(mesh);
343
353
  return portionId;
344
354
  }
345
355
 
@@ -121,6 +121,10 @@ class TrianglesInstancingLayer {
121
121
  this._modelNormalMatrixCol2 = [];
122
122
 
123
123
  this._portions = [];
124
+ this._meshes = [];
125
+
126
+ this._aabb = math.collapseAABB3();
127
+ this.aabbDirty = true;
124
128
 
125
129
  if (cfg.origin) {
126
130
  this._state.origin.set(cfg.origin);
@@ -141,6 +145,17 @@ class TrianglesInstancingLayer {
141
145
  this.numIndices = cfg.geometry.numIndices;
142
146
  }
143
147
 
148
+ get aabb() {
149
+ if (this.aabbDirty) {
150
+ math.collapseAABB3(this._aabb);
151
+ for (let i = 0, len = this._meshes.length; i < len; i++) {
152
+ math.expandAABB3(this._aabb, this._meshes[i].aabb);
153
+ }
154
+ this.aabbDirty = false;
155
+ }
156
+ return this._aabb;
157
+ }
158
+
144
159
  /**
145
160
  * Creates a new portion within this InstancingLayer, returns the new portion ID.
146
161
  *
@@ -148,6 +163,7 @@ class TrianglesInstancingLayer {
148
163
  *
149
164
  * Gives the portion the specified color and matrix.
150
165
  *
166
+ * @param mesh The SceneModelMesh that owns the portion
151
167
  * @param cfg Portion params
152
168
  * @param cfg.color Color [0..255,0..255,0..255]
153
169
  * @param cfg.metallic Metalness factor [0..255]
@@ -158,7 +174,7 @@ class TrianglesInstancingLayer {
158
174
  * @param cfg.pickColor Quantized pick color
159
175
  * @returns {number} Portion ID.
160
176
  */
161
- createPortion(cfg) {
177
+ createPortion(mesh, cfg) {
162
178
 
163
179
  const color = cfg.color;
164
180
  const metallic = cfg.metallic;
@@ -250,7 +266,7 @@ class TrianglesInstancingLayer {
250
266
 
251
267
  this._numPortions++;
252
268
  this.model.numPortions++;
253
-
269
+ this._meshes.push(mesh);
254
270
  return portionId;
255
271
  }
256
272