@xeokit/xeokit-sdk 2.4.2-beta-38 → 2.4.2-beta-40

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 (24) hide show
  1. package/dist/xeokit-sdk.cjs.js +162 -40
  2. package/dist/xeokit-sdk.es.js +162 -40
  3. package/dist/xeokit-sdk.es5.js +264 -251
  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 +2 -2
  7. package/package.json +1 -1
  8. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +10 -5
  9. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +7 -0
  10. package/src/viewer/scene/model/SceneModel.js +1 -1
  11. package/src/viewer/scene/model/SceneModelMesh.js +2 -0
  12. package/src/viewer/scene/model/dtx/triangles/TrianglesDataTextureLayer.js +24 -9
  13. package/src/viewer/scene/model/dtx/triangles/renderers/TrianglesDataTextureSnapDepthBufInitRenderer.js +1 -1
  14. package/src/viewer/scene/model/dtx/triangles/renderers/TrianglesDataTextureSnapDepthRenderer.js +1 -1
  15. package/src/viewer/scene/model/vbo/linesBatching/LinesBatchingLayer.js +19 -3
  16. package/src/viewer/scene/model/vbo/linesInstancing/LinesInstancingLayer.js +19 -1
  17. package/src/viewer/scene/model/vbo/pointsBatching/PointsBatchingLayer.js +21 -6
  18. package/src/viewer/scene/model/vbo/pointsInstancing/PointsInstancingLayer.js +17 -2
  19. package/src/viewer/scene/model/vbo/snapBatching/SnapBatchingDepthBufInitRenderer.js +1 -1
  20. package/src/viewer/scene/model/vbo/snapBatching/SnapBatchingDepthRenderer.js +1 -1
  21. package/src/viewer/scene/model/vbo/snapInstancing/SnapInstancingDepthBufInitRenderer.js +1 -1
  22. package/src/viewer/scene/model/vbo/snapInstancing/SnapInstancingDepthRenderer.js +1 -1
  23. package/src/viewer/scene/model/vbo/trianglesBatching/TrianglesBatchingLayer.js +18 -8
  24. 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-38",
3
+ "version": "2.4.2-beta-40",
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",
@@ -181,7 +181,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
181
181
  const cameraControl = this.angleMeasurementsPlugin.viewer.cameraControl;
182
182
  const pointerLens = this.pointerLens;
183
183
  let mouseHovering = false;
184
- let mouseHoverEntity = false;
184
+ let hoveredEntity = null;
185
185
  let lastMouseCanvasX = 0;
186
186
  let lastMouseCanvasY = 0;
187
187
  const mouseWorldPos = math.vec3();
@@ -213,7 +213,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
213
213
  }
214
214
  const canvasPos = event.snappedCanvasPos || event.canvasPos;
215
215
  mouseHovering = true;
216
- mouseHoverEntity = event.entity;
216
+ hoveredEntity = event.entity;
217
217
  mouseWorldPos.set(event.worldPos);
218
218
  mouseHoverCanvasPos.set(canvasPos);
219
219
  switch (this._mouseState) {
@@ -228,6 +228,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
228
228
  this._currentAngleMeasurement.cornerVisible = true;
229
229
  this._currentAngleMeasurement.angleVisible = false;
230
230
  this._currentAngleMeasurement.corner.worldPos = event.worldPos;
231
+ this._currentAngleMeasurement.corner.entity = event.entity;
231
232
  }
232
233
  this.markerDiv.style.marginLeft = `-10000px`;
233
234
  this.markerDiv.style.marginTop = `-10000px`;
@@ -239,6 +240,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
239
240
  this._currentAngleMeasurement.targetVisible = true;
240
241
  this._currentAngleMeasurement.angleVisible = true;
241
242
  this._currentAngleMeasurement.target.worldPos = event.worldPos;
243
+ this._currentAngleMeasurement.target.entity = event.entity;
242
244
  }
243
245
  this.markerDiv.style.marginLeft = `-10000px`;
244
246
  this.markerDiv.style.marginTop = `-10000px`;
@@ -269,15 +271,12 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
269
271
  this._currentAngleMeasurement = this.angleMeasurementsPlugin.createMeasurement({
270
272
  id: math.createUUID(),
271
273
  origin: {
272
- entity: mouseHoverEntity,
273
274
  worldPos: mouseWorldPos
274
275
  },
275
276
  corner: {
276
- entity: mouseHoverEntity,
277
277
  worldPos: mouseWorldPos
278
278
  },
279
279
  target: {
280
- entity: mouseHoverEntity,
281
280
  worldPos: mouseWorldPos
282
281
  },
283
282
  approximate: true
@@ -289,6 +288,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
289
288
  this._currentAngleMeasurement.targetWireVisible = false;
290
289
  this._currentAngleMeasurement.targetVisible = false;
291
290
  this._currentAngleMeasurement.angleVisible = false;
291
+ this._currentAngleMeasurement.origin.entity = hoveredEntity;
292
292
  this._mouseState = MOUSE_FINDING_CORNER;
293
293
  this.angleMeasurementsPlugin.fire("measurementStart", this._currentAngleMeasurement);
294
294
  }
@@ -298,11 +298,13 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
298
298
  this._currentAngleMeasurement.targetWireVisible = false;
299
299
  this._currentAngleMeasurement.targetVisible = true;
300
300
  this._currentAngleMeasurement.angleVisible = true;
301
+ this._currentAngleMeasurement.corner.entity = hoveredEntity;
301
302
  this._mouseState = MOUSE_FINDING_TARGET;
302
303
  } else {
303
304
  if (this._currentAngleMeasurement) {
304
305
  this._currentAngleMeasurement.destroy();
305
306
  this._currentAngleMeasurement = null;
307
+ hoveredEntity = null;
306
308
  this._mouseState = MOUSE_FINDING_ORIGIN
307
309
  this.angleMeasurementsPlugin.fire("measurementCancel", this._currentAngleMeasurement);
308
310
  }
@@ -312,7 +314,9 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
312
314
  if (mouseHovering) {
313
315
  this._currentAngleMeasurement.targetVisible = true;
314
316
  this._currentAngleMeasurement.angleVisible = true;
317
+ this._currentAngleMeasurement.target.entity = hoveredEntity;
315
318
  this._currentAngleMeasurement.clickable = true;
319
+ hoveredEntity = null;
316
320
  this.angleMeasurementsPlugin.fire("measurementEnd", this._currentAngleMeasurement);
317
321
  this._currentAngleMeasurement = null;
318
322
  this._mouseState = MOUSE_FINDING_ORIGIN;
@@ -320,6 +324,7 @@ export class AngleMeasurementsMouseControl extends AngleMeasurementsControl {
320
324
  if (this._currentAngleMeasurement) {
321
325
  this._currentAngleMeasurement.destroy();
322
326
  this._currentAngleMeasurement = null;
327
+ hoveredEntity = null;
323
328
  this._mouseState = MOUSE_FINDING_ORIGIN;
324
329
  this.angleMeasurementsPlugin.fire("measurementCancel", this._currentAngleMeasurement);
325
330
  }
@@ -191,6 +191,7 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
191
191
  let pointerDownCanvasX;
192
192
  let pointerDownCanvasY;
193
193
  const clickTolerance = 20;
194
+ let hoveredEntity = null;
194
195
 
195
196
  this._mouseState = MOUSE_FIRST_CLICK_EXPECTED;
196
197
 
@@ -225,6 +226,7 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
225
226
  this._markerDiv.style.background = "pink";
226
227
  this._markerDiv.style.border = "2px solid red";
227
228
  }
229
+ hoveredEntity = event.entity;
228
230
  } else {
229
231
  this._markerDiv.style.marginLeft = `-10000px`;
230
232
  this._markerDiv.style.marginTop = `-10000px`;
@@ -263,6 +265,8 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
263
265
  }
264
266
  if (this._currentDistanceMeasurement) {
265
267
  if (mouseHovering) {
268
+ this._currentDistanceMeasurement.target.entity = hoveredEntity;
269
+ hoveredEntity = null;
266
270
  this._currentDistanceMeasurement.clickable = true;
267
271
  this.distanceMeasurementsPlugin.fire("measurementEnd", this._currentDistanceMeasurement);
268
272
  this._currentDistanceMeasurement = null;
@@ -270,6 +274,7 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
270
274
  this._currentDistanceMeasurement.destroy();
271
275
  this.distanceMeasurementsPlugin.fire("measurementCancel", this._currentDistanceMeasurement);
272
276
  this._currentDistanceMeasurement = null;
277
+ hoveredEntity = null;
273
278
  }
274
279
  } else {
275
280
  if (mouseHovering) {
@@ -290,6 +295,8 @@ export class DistanceMeasurementsMouseControl extends DistanceMeasurementsContro
290
295
  this._currentDistanceMeasurementInitState.wireVisible = this._currentDistanceMeasurement.wireVisible;
291
296
  this._currentDistanceMeasurementInitState.targetVisible = this._currentDistanceMeasurement.targetVisible;
292
297
  this._currentDistanceMeasurement.clickable = false;
298
+ this._currentDistanceMeasurement.origin.entity = hoveredEntity;
299
+ hoveredEntity = null;
293
300
  this.fire("measurementStart", this._currentDistanceMeasurement);
294
301
  }
295
302
  }
@@ -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 = model.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 = model.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