@xeokit/xeokit-sdk 2.6.28 → 2.6.30

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 (58) hide show
  1. package/README.md +1 -0
  2. package/dist/xeokit-sdk.cjs.js +1425 -649
  3. package/dist/xeokit-sdk.es.js +1420 -650
  4. package/dist/xeokit-sdk.es5.js +629 -552
  5. package/dist/xeokit-sdk.min.cjs.js +5 -5
  6. package/dist/xeokit-sdk.min.es.js +5 -5
  7. package/dist/xeokit-sdk.min.es5.js +4 -4
  8. package/package.json +1 -1
  9. package/src/extras/PointerCircle/PointerCircle.js +1 -1
  10. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsMouseControl.js +22 -41
  11. package/src/plugins/AngleMeasurementsPlugin/AngleMeasurementsTouchControl.js +3 -18
  12. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsMouseControl.js +20 -41
  13. package/src/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsTouchControl.js +4 -20
  14. package/src/plugins/DistanceMeasurementsPlugin/index.js +1 -1
  15. package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +2 -110
  16. package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +252 -222
  17. package/src/plugins/StoreyViewsPlugin/StoreyViewsPlugin.js +31 -1
  18. package/src/plugins/XKTLoaderPlugin/XKTLoaderPlugin.js +20 -8
  19. package/src/plugins/ZonesPlugin/ZonesPlugin.js +1939 -0
  20. package/src/plugins/ZonesPlugin/index.js +1 -1875
  21. package/src/viewer/Viewer.js +2 -2
  22. package/src/viewer/metadata/MetaScene.js +0 -2
  23. package/src/viewer/scene/math/MeshSurfaceArea.js +90 -0
  24. package/src/viewer/scene/math/MeshVolume.js +102 -0
  25. package/src/viewer/scene/math/index.js +3 -0
  26. package/src/viewer/scene/math/isTriangleMeshSolid.js +162 -0
  27. package/src/viewer/scene/math/math.js +8 -0
  28. package/src/viewer/scene/model/SceneModel.js +73 -34
  29. package/src/viewer/scene/model/SceneModelEntity.js +46 -1
  30. package/src/viewer/scene/model/SceneModelMesh.js +74 -1
  31. package/src/viewer/scene/model/SceneModelTextureSet.js +5 -0
  32. package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +7 -1
  33. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +77 -1
  34. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +8 -0
  35. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +8 -0
  36. package/src/viewer/scene/model/vbo/VBORenderer.js +10 -1
  37. package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +6 -1
  38. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +1 -1
  39. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +6 -1
  40. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +59 -18
  41. package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +40 -12
  42. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +2 -3
  43. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +25 -7
  44. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +1 -1
  45. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +6 -1
  46. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +1 -1
  47. package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +6 -1
  48. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +48 -14
  49. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +74 -47
  50. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +29 -14
  51. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +5 -4
  52. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +1 -1
  53. package/src/viewer/scene/scene/Scene.js +16 -5
  54. package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +1 -1
  55. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +1 -5
  56. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurement.d.ts +7 -0
  57. package/types/plugins/DistanceMeasurementsPlugin/DistanceMeasurementsPlugin.d.ts +26 -1
  58. package/types/plugins/DistanceMeasurementsPlugin/index.d.ts +3 -1
@@ -633,7 +633,7 @@ export class SceneModelEntity {
633
633
  for (let i = 0, len = this.meshes.length; i < len; i++) {
634
634
  this.meshes[i]._setOffset(this._offset);
635
635
  }
636
- this._aabbDirty = true;
636
+ this._aabbDirty = true;
637
637
  this.model._aabbDirty = true;
638
638
  this.scene._aabbDirty = true;
639
639
  this.scene._objectOffsetUpdated(this, offset);
@@ -650,6 +650,51 @@ export class SceneModelEntity {
650
650
  }
651
651
  }
652
652
 
653
+ getEachIndex(callback) {
654
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
655
+ this.meshes[i].getEachIndex(callback)
656
+ }
657
+ }
658
+
659
+ /**
660
+ * Returns the volume of this SceneModelEntity.
661
+ *
662
+ * Only works when {@link Scene.readableGeometryEnabled | Scene.readableGeometryEnabled} is `true` and the
663
+ * SceneModelEntity contains solid triangle meshes; returns `0` otherwise.
664
+ *
665
+ * @returns {number}
666
+ */
667
+ get volume() {
668
+ let volume = 0;
669
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
670
+ const meshVolume = this.meshes[i].volume;
671
+ if (meshVolume < 0) {
672
+ return -1;
673
+ }
674
+ volume += meshVolume;
675
+ }
676
+ return volume;
677
+ }
678
+
679
+ /**
680
+ * Returns the surface area of this SceneModelEntity.
681
+ *
682
+ * Only works when {@link Scene.readableGeometryEnabled | Scene.readableGeometryEnabled} is `true` and the
683
+ * SceneModelEntity contains triangle meshes; returns `0` otherwise.
684
+ *
685
+ * @returns {number}
686
+ */
687
+ get surfaceArea() {
688
+ let surfaceArea = 0;
689
+ for (let i = 0, len = this.meshes.length; i < len; i++) {
690
+ const meshSurfaceArea = this.meshes[i].surfaceArea;
691
+ if (meshSurfaceArea >= 0) {
692
+ surfaceArea += meshSurfaceArea;
693
+ }
694
+ }
695
+ return surfaceArea > 0 ? surfaceArea : -1;
696
+ }
697
+
653
698
  _getFlag(flag) {
654
699
  return !!(this._flags & flag);
655
700
  }
@@ -1,9 +1,11 @@
1
1
  import {math} from "../math/math.js";
2
+ import {meshSurfaceArea, meshVolume} from "../math/index.js";
2
3
 
3
4
  const tempOBB3 = math.OBB3();
4
5
  const tempOBB3b = math.OBB3();
5
6
  const tempOBB3c = math.OBB3();
6
7
 
8
+
7
9
  /**
8
10
  * A mesh within a {@link SceneModel}.
9
11
  *
@@ -116,6 +118,9 @@ export class SceneModelMesh {
116
118
  if (transform) {
117
119
  transform._addMesh(this);
118
120
  }
121
+
122
+ this._volume = null;
123
+ this._surfaceArea = null;
119
124
  }
120
125
 
121
126
  _sceneModelDirty() {
@@ -294,7 +299,75 @@ export class SceneModelMesh {
294
299
  * @private
295
300
  */
296
301
  getEachVertex(callback) {
297
- this.layer.getEachVertex(this.portionId, callback);
302
+ if (this.layer.getEachVertex) {
303
+ this.layer.getEachVertex(this.portionId, callback);
304
+ }
305
+ }
306
+
307
+ /**
308
+ * @private
309
+ */
310
+ getEachIndex(callback) {
311
+ if (this.layer.getEachIndex ) {
312
+ this.layer.getEachIndex(this.portionId, callback);
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Returns the volume of this SceneModelMesh.
318
+ * @returns {number}
319
+ */
320
+ get volume() {
321
+ if (this._volume !== null) {
322
+ return this._volume;
323
+ }
324
+ switch (this.layer.primitive) {
325
+ case "solid":
326
+ case "surface":
327
+ case "triangles":
328
+ meshVolume.reset();
329
+ meshVolume.setPrimitive(this.layer.primitive);
330
+ this.getEachVertex((vertex) =>{
331
+ meshVolume.addVertex(vertex);
332
+ });
333
+ this.getEachIndex((index)=>{
334
+ meshVolume.addIndex(index);
335
+ });
336
+ this._volume = meshVolume.volume;
337
+ break;
338
+ default:
339
+ this._volume = 0;
340
+ break;
341
+ }
342
+ return this._volume;
343
+ }
344
+
345
+ /**
346
+ * Returns the surface area of this SceneModelMesh.
347
+ * @returns {number}
348
+ */
349
+ get surfaceArea() {
350
+ if (this._surfaceArea !== null) {
351
+ return this._surfaceArea;
352
+ }
353
+ switch (this.layer.primitive) {
354
+ case "solid":
355
+ case "surface":
356
+ case "triangles":
357
+ meshSurfaceArea.reset();
358
+ this.getEachVertex((vertex) =>{
359
+ meshSurfaceArea.addVertex(vertex);
360
+ });
361
+ this.getEachIndex((index)=>{
362
+ meshSurfaceArea.addIndex(index);
363
+ });
364
+ this._surfaceArea = meshSurfaceArea.surfaceArea;
365
+ break;
366
+ default:
367
+ this._surfaceArea = 0;
368
+ break;
369
+ }
370
+ return this._surfaceArea;
298
371
  }
299
372
 
300
373
  /**
@@ -26,6 +26,11 @@ export class SceneModelTextureSet {
26
26
  */
27
27
  this.colorTexture = cfg.colorTexture;
28
28
 
29
+ /**
30
+ * The alpha cutoff [float]
31
+ */
32
+ this.alphaCutoff = cfg.alphaCutoff;
33
+
29
34
  /**
30
35
  * The metallic-roughness texture.
31
36
  * @type {SceneModelTexture|*}
@@ -31,7 +31,7 @@ export class DTXLinesLayer {
31
31
 
32
32
  constructor(model, cfg) {
33
33
 
34
- console.info("Creating DTXLinesLayer");
34
+ // console.info("Creating DTXLinesLayer");
35
35
 
36
36
  dataTextureRamStats.numberOfLayers++;
37
37
 
@@ -70,6 +70,12 @@ export class DTXLinesLayer {
70
70
  this._aabb = math.collapseAABB3();
71
71
  this.aabbDirty = true;
72
72
  this._numUpdatesInFrame = 0;
73
+
74
+ /**
75
+ * The type of primitives in this layer.
76
+ */
77
+ this.primitive = cfg.primitive;
78
+
73
79
  this._finalized = false;
74
80
  }
75
81
 
@@ -38,6 +38,7 @@ const INDICES_EDGE_INDICES_ALIGNEMENT_SIZE = 8;
38
38
  */
39
39
  const MAX_OBJECT_UPDATES_IN_FRAME_WITHOUT_BATCHED_UPDATE = 10;
40
40
 
41
+ const tempVec4a = math.vec4();
41
42
  const tempMat4a = new Float32Array(16);
42
43
  const tempUint8Array4 = new Uint8Array(4);
43
44
  const tempFloat32Array3 = new Float32Array(3);
@@ -53,7 +54,7 @@ export class DTXTrianglesLayer {
53
54
 
54
55
  constructor(model, cfg) {
55
56
 
56
- console.info("Creating DTXTrianglesLayer");
57
+ //console.info("Creating DTXTrianglesLayer");
57
58
 
58
59
  dataTextureRamStats.numberOfLayers++;
59
60
 
@@ -93,6 +94,10 @@ export class DTXTrianglesLayer {
93
94
 
94
95
  this._subPortions = [];
95
96
 
97
+ if (this.model.scene.readableGeometryEnabled) {
98
+ this._subPortionReadableGeometries = {};
99
+ }
100
+
96
101
  /**
97
102
  * Due to `index rebucketting` process in ```prepareMeshGeometry``` function, it's possible that a single
98
103
  * portion is expanded to more than 1 real sub-portion.
@@ -122,6 +127,11 @@ export class DTXTrianglesLayer {
122
127
  */
123
128
  this._numUpdatesInFrame = 0;
124
129
 
130
+ /**
131
+ * The type of primitives in this layer.
132
+ */
133
+ this.primitive = cfg.primitive;
134
+
125
135
  this._finalized = false;
126
136
  }
127
137
 
@@ -426,6 +436,15 @@ export class DTXTrianglesLayer {
426
436
  numVertices: bucketGeometry.numTriangles
427
437
  });
428
438
 
439
+ if (this.model.scene.readableGeometryEnabled) {
440
+ this._subPortionReadableGeometries[subPortionId] = {
441
+ indices: bucket.indices,
442
+ positionsCompressed: bucket.positionsCompressed,
443
+ positionsDecodeMatrix: portionCfg.positionsDecodeMatrix,
444
+ meshMatrix: portionCfg.meshMatrix
445
+ };
446
+ }
447
+
429
448
  this._numPortions++;
430
449
 
431
450
  dataTextureRamStats.numberOfPortions++;
@@ -1076,6 +1095,63 @@ export class DTXTrianglesLayer {
1076
1095
  // gl.bindTexture (gl.TEXTURE_2D, null);
1077
1096
  }
1078
1097
 
1098
+ getEachVertex(portionId, callback) {
1099
+ if (!this.model.scene.readableGeometryEnabled) {
1100
+ return;
1101
+ }
1102
+ const state = this._state;
1103
+ const subPortionIds = this._portionToSubPortionsMap[portionId];
1104
+ if (!subPortionIds) {
1105
+ this.model.error("portion not found: " + portionId);
1106
+ return;
1107
+ }
1108
+ for (let i = 0, len = subPortionIds.length; i < len; i++) {
1109
+ const subPortionId = subPortionIds[i];
1110
+ const subPortionReadableGeometry = this._subPortionReadableGeometries[subPortionId];
1111
+ const positions = subPortionReadableGeometry.positionsCompressed;
1112
+ const positionsDecodeMatrix = subPortionReadableGeometry.positionsDecodeMatrix;
1113
+ const meshMatrix = subPortionReadableGeometry.meshMatrix;
1114
+ const origin = state.origin;
1115
+ const offsetX = origin[0] ;
1116
+ const offsetY = origin[1] ;
1117
+ const offsetZ = origin[2] ;
1118
+ const worldPos = tempVec4a;
1119
+ for (let i = 0, len = positions.length; i < len; i += 3) {
1120
+ worldPos[0] = positions[i];
1121
+ worldPos[1] = positions[i + 1];
1122
+ worldPos[2] = positions[i + 2];
1123
+ worldPos[3] = 1.0;
1124
+ math.decompressPosition(worldPos, positionsDecodeMatrix);
1125
+ math.transformPoint4(this.model.worldMatrix, worldPos);
1126
+ math.transformPoint4(this.model.worldMatrix, worldPos);
1127
+ worldPos[0] += offsetX;
1128
+ worldPos[1] += offsetY;
1129
+ worldPos[2] += offsetZ;
1130
+ callback(worldPos);
1131
+ }
1132
+ }
1133
+ }
1134
+
1135
+ getEachIndex(portionId, callback) {
1136
+ if (!this.model.scene.readableGeometryEnabled) {
1137
+ return;
1138
+ }
1139
+ const subPortionIds = this._portionToSubPortionsMap[portionId];
1140
+ if (!subPortionIds) {
1141
+ this.model.error("portion not found: " + portionId);
1142
+ return;
1143
+ }
1144
+ for (let i = 0, len = subPortionIds.length; i < len; i++) {
1145
+ const subPortionId = subPortionIds[i];
1146
+ const subPortionReadableGeometry = this._subPortionReadableGeometries[subPortionId];
1147
+ const indices = subPortionReadableGeometry.indices;
1148
+ for (let i = 0, len = indices.length; i < len; i++) {
1149
+ callback(indices[i]);
1150
+ }
1151
+ }
1152
+ }
1153
+
1154
+
1079
1155
  // ---------------------- COLOR RENDERING -----------------------------------
1080
1156
 
1081
1157
  drawColorOpaque(renderFlags, frameCtx) {
@@ -304,6 +304,14 @@ export class DTXTrianglesSnapInitRenderer {
304
304
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
305
305
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
306
306
 
307
+ // flags.w = NOT_RENDERED | PICK
308
+ // renderPass = PICK
309
+
310
+ src.push(`if (int(flags.w) != renderPass) {`);
311
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
312
+ src.push(" return;"); // Cull vertex
313
+ src.push("}");
314
+
307
315
  src.push("{");
308
316
 
309
317
  // get color
@@ -311,6 +311,14 @@ export class DTXTrianglesSnapRenderer {
311
311
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
312
312
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
313
313
 
314
+ // flags.w = NOT_RENDERED | PICK
315
+ // renderPass = PICK
316
+
317
+ src.push(`if (int(flags.w) != renderPass) {`);
318
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
319
+ src.push(" return;"); // Cull vertex
320
+ src.push("}");
321
+
314
322
  src.push("{");
315
323
 
316
324
  // get vertex base
@@ -17,11 +17,12 @@ const tempMat4a = math.mat4();
17
17
  * @private
18
18
  */
19
19
  export class VBORenderer {
20
- constructor(scene, withSAO = false, {instancing = false, edges = false} = {}) {
20
+ constructor(scene, withSAO = false, {instancing = false, edges = false, useAlphaCutoff = false} = {}) {
21
21
  this._scene = scene;
22
22
  this._withSAO = withSAO;
23
23
  this._instancing = instancing;
24
24
  this._edges = edges;
25
+ this._useAlphaCutoff = useAlphaCutoff;
25
26
  this._hash = this._getHash();
26
27
 
27
28
  /**
@@ -272,6 +273,10 @@ export class VBORenderer {
272
273
  this._uSAOParams = program.getLocation("uSAOParams");
273
274
  }
274
275
 
276
+ if (this._useAlphaCutoff) {
277
+ this._alphaCutoffLocation = program.getLocation("materialAlphaCutoff");
278
+ }
279
+
275
280
  if (scene.logarithmicDepthBufferEnabled) {
276
281
  this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
277
282
  }
@@ -609,6 +614,10 @@ export class VBORenderer {
609
614
  }
610
615
  }
611
616
 
617
+ if (this._useAlphaCutoff) {
618
+ gl.uniform1f(this._alphaCutoffLocation, textureSet.alphaCutoff);
619
+ }
620
+
612
621
  if (colorUniform) {
613
622
  const colorKey = this._edges ? "edgeColor" : "fillColor";
614
623
  const alphaKey = this._edges ? "edgeAlpha" : "fillAlpha";
@@ -24,7 +24,7 @@ export class VBOBatchingLinesLayer {
24
24
  */
25
25
  constructor(cfg) {
26
26
 
27
- console.info("Creating VBOBatchingLinesLayer");
27
+ // console.info("Creating VBOBatchingLinesLayer");
28
28
 
29
29
  /**
30
30
  * Index of this LinesBatchingLayer in {@link VBOSceneModel#_layerList}.
@@ -79,6 +79,11 @@ export class VBOBatchingLinesLayer {
79
79
  if (cfg.origin) {
80
80
  this._state.origin = math.vec3(cfg.origin);
81
81
  }
82
+
83
+ /**
84
+ * The type of primitives in this layer.
85
+ */
86
+ this.primitive = cfg.primitive;
82
87
  }
83
88
 
84
89
  get aabb() {
@@ -215,7 +215,7 @@ export class VBOBatchingLinesSnapRenderer extends VBORenderer{
215
215
 
216
216
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
217
217
  src.push(`if (pickFlag != renderPass) {`);
218
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
218
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
219
219
  src.push(" } else {");
220
220
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
221
221
  if (scene.entityOffsetsEnabled) {
@@ -24,7 +24,7 @@ export class VBOBatchingPointsLayer {
24
24
  */
25
25
  constructor(cfg) {
26
26
 
27
- console.info("Creating VBOBatchingPointsLayer");
27
+ // console.info("Creating VBOBatchingPointsLayer");
28
28
 
29
29
  /**
30
30
  * Owner model
@@ -99,6 +99,11 @@ export class VBOBatchingPointsLayer {
99
99
  this.aabbDirty = false;
100
100
  }
101
101
  return this._aabb;
102
+
103
+ /**
104
+ * The type of primitives in this layer.
105
+ */
106
+ this.primitive = cfg.primitive;
102
107
  }
103
108
 
104
109
  /**
@@ -41,7 +41,7 @@ export class VBOBatchingTrianglesLayer {
41
41
  */
42
42
  constructor(cfg) {
43
43
 
44
- console.info("Creating VBOBatchingTrianglesLayer");
44
+ // console.info("Creating VBOBatchingTrianglesLayer");
45
45
 
46
46
  /**
47
47
  * Owner model
@@ -131,6 +131,11 @@ export class VBOBatchingTrianglesLayer {
131
131
  * @type {boolean}
132
132
  */
133
133
  this.solid = !!cfg.solid;
134
+
135
+ /**
136
+ * The type of primitives in this layer.
137
+ */
138
+ this.primitive = cfg.primitive;
134
139
  }
135
140
 
136
141
  get aabb() {
@@ -327,7 +332,7 @@ export class VBOBatchingTrianglesLayer {
327
332
  numIndices: indices.length,
328
333
  };
329
334
 
330
- if (scene.pickSurfacePrecisionEnabled) {
335
+ if (scene.readableGeometryEnabled) {
331
336
  // Quantized in-memory positions are initialized in finalize()
332
337
 
333
338
  portion.indices = indices;
@@ -364,7 +369,7 @@ export class VBOBatchingTrianglesLayer {
364
369
  ? new Uint16Array(buffer.positions)
365
370
  : quantizePositions(buffer.positions, this._modelAABB, this._state.positionsDecodeMatrix = math.mat4()); // BOTTLENECK
366
371
  state.positionsBuf = new ArrayBuf(gl, gl.ARRAY_BUFFER, quantizedPositions, quantizedPositions.length, 3, gl.STATIC_DRAW);
367
- if (this.model.scene.pickSurfacePrecisionEnabled) {
372
+ if (this.model.scene.readableGeometryEnabled) {
368
373
  for (let i = 0, numPortions = this._portions.length; i < numPortions; i++) {
369
374
  const portion = this._portions[i];
370
375
  const start = portion.vertsBaseIndex * 3;
@@ -793,7 +798,7 @@ export class VBOBatchingTrianglesLayer {
793
798
  if (this._state.offsetsBuf) {
794
799
  this._state.offsetsBuf.setData(tempArray, firstOffset, lenOffsets);
795
800
  }
796
- if (this.model.scene.pickSurfacePrecisionEnabled) {
801
+ if (this.model.scene.readableGeometryEnabled) {
797
802
  portion.offset[0] = offset[0];
798
803
  portion.offset[1] = offset[1];
799
804
  portion.offset[2] = offset[2];
@@ -801,7 +806,7 @@ export class VBOBatchingTrianglesLayer {
801
806
  }
802
807
 
803
808
  getEachVertex(portionId, callback) {
804
- if (!this.model.scene.pickSurfacePrecisionEnabled) {
809
+ if (!this.model.scene.readableGeometryEnabled) {
805
810
  return;
806
811
  }
807
812
  const state = this._state;
@@ -812,18 +817,19 @@ export class VBOBatchingTrianglesLayer {
812
817
  }
813
818
  const positions = portion.quantizedPositions;
814
819
  const origin = state.origin;
815
- const offset = portion.offset;
816
- const offsetX = origin[0] + offset[0];
817
- const offsetY = origin[1] + offset[1];
818
- const offsetZ = origin[2] + offset[2];
820
+ const offsetX = origin[0] ;
821
+ const offsetY = origin[1] ;
822
+ const offsetZ = origin[2] ;
819
823
  const worldPos = tempVec4a;
824
+ const sceneModelMatrix = this.model.matrix;
825
+ const positionsDecodeMatrix = state.positionsDecodeMatrix;
820
826
  for (let i = 0, len = positions.length; i < len; i += 3) {
821
827
  worldPos[0] = positions[i];
822
828
  worldPos[1] = positions[i + 1];
823
829
  worldPos[2] = positions[i + 2];
824
830
  worldPos[3] = 1.0;
825
- math.decompressPosition(worldPos, state.positionsDecodeMatrix);
826
- math.transformPoint4(this.model.worldMatrix, worldPos);
831
+ math.decompressPosition(worldPos, positionsDecodeMatrix);
832
+ math.transformPoint4(sceneModelMatrix, worldPos);
827
833
  worldPos[0] += offsetX;
828
834
  worldPos[1] += offsetY;
829
835
  worldPos[2] += offsetZ;
@@ -831,6 +837,21 @@ export class VBOBatchingTrianglesLayer {
831
837
  }
832
838
  }
833
839
 
840
+ getEachIndex(portionId, callback) {
841
+ if (!this.model.scene.readableGeometryEnabled) {
842
+ return;
843
+ }
844
+ const portion = this._portions[portionId];
845
+ if (!portion) {
846
+ this.model.error("portion not found: " + portionId);
847
+ return;
848
+ }
849
+ const indices = portion.indices;
850
+ for (let i = 0, len = indices.length; i < len; i++) {
851
+ callback(indices[i]);
852
+ }
853
+ }
854
+
834
855
  getElementsCountAndOffset(portionId) {
835
856
  let count = null;
836
857
  let offset = null;
@@ -851,14 +872,21 @@ export class VBOBatchingTrianglesLayer {
851
872
  return;
852
873
  }
853
874
  this._updateBackfaceCull(renderFlags, frameCtx);
875
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
854
876
  if (frameCtx.withSAO && this.model.saoEnabled) {
855
877
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
856
878
  if (this._renderers.pbrRendererWithSAO) {
857
879
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
858
880
  }
859
881
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
860
- if (this._renderers.colorTextureRendererWithSAO) {
861
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
882
+ if (useAlphaCutoff) {
883
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
884
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
885
+ }
886
+ } else {
887
+ if (this._renderers.colorTextureRendererWithSAO) {
888
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
889
+ }
862
890
  }
863
891
  } else if (this._state.normalsBuf) {
864
892
  if (this._renderers.colorRendererWithSAO) {
@@ -875,8 +903,14 @@ export class VBOBatchingTrianglesLayer {
875
903
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
876
904
  }
877
905
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
878
- if (this._renderers.colorTextureRenderer) {
879
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
906
+ if (useAlphaCutoff) {
907
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
908
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
909
+ }
910
+ } else {
911
+ if (this._renderers.colorTextureRenderer) {
912
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
913
+ }
880
914
  }
881
915
  } else if (this._state.normalsBuf) {
882
916
  if (this._renderers.colorRenderer) {
@@ -913,8 +947,15 @@ export class VBOBatchingTrianglesLayer {
913
947
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
914
948
  }
915
949
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
916
- if (this._renderers.colorTextureRenderer) {
917
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
950
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
951
+ if (useAlphaCutoff) {
952
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
953
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
954
+ }
955
+ } else {
956
+ if (this._renderers.colorTextureRenderer) {
957
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
958
+ }
918
959
  }
919
960
  } else if (this._state.normalsBuf) {
920
961
  if (this._renderers.colorRenderer) {
@@ -1118,7 +1159,7 @@ export class VBOBatchingTrianglesLayer {
1118
1159
 
1119
1160
  precisionRayPickSurface(portionId, worldRayOrigin, worldRayDir, worldSurfacePos, worldNormal) {
1120
1161
 
1121
- if (!this.model.scene.pickSurfacePrecisionEnabled) {
1162
+ if (!this.model.scene.readableGeometryEnabled) {
1122
1163
  return false;
1123
1164
  }
1124
1165