@xeokit/xeokit-sdk 2.6.29 → 2.6.31

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 (35) hide show
  1. package/dist/xeokit-sdk.cjs.js +635 -468
  2. package/dist/xeokit-sdk.es.js +635 -468
  3. package/dist/xeokit-sdk.es5.js +318 -330
  4. package/dist/xeokit-sdk.min.cjs.js +4 -4
  5. package/dist/xeokit-sdk.min.es.js +5 -5
  6. package/dist/xeokit-sdk.min.es5.js +3 -3
  7. package/package.json +1 -1
  8. package/src/plugins/DotBIMLoaderPlugin/DotBIMLoaderPlugin.js +110 -33
  9. package/src/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.js +2 -110
  10. package/src/plugins/GLTFLoaderPlugin/GLTFSceneModelLoader.js +257 -222
  11. package/src/plugins/TreeViewPlugin/TreeViewPlugin.js +1 -1
  12. package/src/viewer/metadata/MetaScene.js +0 -2
  13. package/src/viewer/scene/model/SceneModel.js +9 -0
  14. package/src/viewer/scene/model/SceneModelTextureSet.js +5 -0
  15. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +8 -0
  16. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +8 -0
  17. package/src/viewer/scene/model/vbo/VBORenderer.js +10 -1
  18. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +1 -1
  19. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +26 -6
  20. package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +40 -12
  21. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +2 -3
  22. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +25 -7
  23. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +1 -1
  24. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +1 -1
  25. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +17 -4
  26. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +74 -47
  27. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +29 -14
  28. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +5 -4
  29. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +1 -1
  30. package/src/viewer/scene/webgl/Renderer.js +6 -3
  31. package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +1 -1
  32. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +1 -4
  33. package/types/plugins/GLTFLoaderPlugin/GLTFLoaderPlugin.d.ts +5 -3
  34. package/types/plugins/LASLoaderPlugin/LASLoaderPlugin.d.ts +2 -2
  35. package/types/plugins/OBJLoaderPlugin/OBJLoaderPlugin.d.ts +3 -3
@@ -17467,7 +17467,7 @@ class OcclusionLayer {
17467
17467
  for (let i = 0; i < this.numMarkers; i++) {
17468
17468
  if (this.markerList[i]) {
17469
17469
  const marker = this.markerList[i];
17470
- const worldPos = marker.worldPos;
17470
+ const worldPos = marker.rtcPos;
17471
17471
  this.positions[j++] = worldPos[0];
17472
17472
  this.positions[j++] = worldPos[1];
17473
17473
  this.positions[j++] = worldPos[2];
@@ -17909,10 +17909,7 @@ class OcclusionTester {
17909
17909
  continue;
17910
17910
  }
17911
17911
 
17912
- // The `origin` has been changed from `occlusionLayer.origin` to `[ 0, 0, 0 ]`
17913
- // because OcclusionLayer markers' transformation is being applied through the
17914
- // OcclusionLayer::positions array. See XEOK-33
17915
- const origin = [ 0, 0, 0 ];
17912
+ const origin = occlusionLayer.origin;
17916
17913
 
17917
17914
  gl.uniformMatrix4fv(this._uViewMatrix, false, createRTCViewMat(camera.viewMatrix, origin));
17918
17915
 
@@ -20503,6 +20500,8 @@ const Renderer$1 = function (scene, options) {
20503
20500
  // result 1) regular hi-precision world position
20504
20501
 
20505
20502
  let worldPos = null;
20503
+ let worldNormal = null;
20504
+ let pickable = null;
20506
20505
 
20507
20506
  const middleX = snapRadiusInPixels;
20508
20507
  const middleY = snapRadiusInPixels;
@@ -20520,7 +20519,7 @@ const Renderer$1 = function (scene, options) {
20520
20519
  pickResultMiddleXY[1] * scale[1] + origin[1],
20521
20520
  pickResultMiddleXY[2] * scale[2] + origin[2],
20522
20521
  ];
20523
- math.normalizeVec3([
20522
+ worldNormal = math.normalizeVec3([
20524
20523
  pickNormalResultMiddleXY[0] / math.MAX_INT,
20525
20524
  pickNormalResultMiddleXY[1] / math.MAX_INT,
20526
20525
  pickNormalResultMiddleXY[2] / math.MAX_INT,
@@ -20532,7 +20531,7 @@ const Renderer$1 = function (scene, options) {
20532
20531
  + (pickPickableResultMiddleXY[2] << 16)
20533
20532
  + (pickPickableResultMiddleXY[3] << 24);
20534
20533
 
20535
- pickIDs.items[pickID];
20534
+ pickable = pickIDs.items[pickID];
20536
20535
  }
20537
20536
 
20538
20537
  // result 2) hi-precision snapped (to vertex/edge) world position
@@ -20629,13 +20628,16 @@ const Renderer$1 = function (scene, options) {
20629
20628
  }
20630
20629
 
20631
20630
  const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
20631
+ if (!snappedEntity && pickable) {
20632
+ pickable = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;
20633
+ }
20632
20634
 
20633
20635
  pickResult.reset();
20634
20636
  pickResult.snappedToEdge = (snapType === "edge");
20635
20637
  pickResult.snappedToVertex = (snapType === "vertex");
20636
- pickResult.worldPos = snappedWorldPos;
20637
- pickResult.worldNormal = snappedWorldNormal;
20638
- pickResult.entity = snappedEntity;
20638
+ pickResult.worldPos = snappedWorldPos || worldPos;
20639
+ pickResult.worldNormal = snappedWorldNormal || worldNormal;
20640
+ pickResult.entity = snappedEntity || pickable;
20639
20641
  pickResult.canvasPos = canvasPos || scene.camera.projectWorldPos(worldPos || snappedWorldPos);
20640
20642
  pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
20641
20643
 
@@ -51502,11 +51504,12 @@ const tempMat4a$r = math.mat4();
51502
51504
  * @private
51503
51505
  */
51504
51506
  class VBORenderer {
51505
- constructor(scene, withSAO = false, {instancing = false, edges = false} = {}) {
51507
+ constructor(scene, withSAO = false, {instancing = false, edges = false, useAlphaCutoff = false} = {}) {
51506
51508
  this._scene = scene;
51507
51509
  this._withSAO = withSAO;
51508
51510
  this._instancing = instancing;
51509
51511
  this._edges = edges;
51512
+ this._useAlphaCutoff = useAlphaCutoff;
51510
51513
  this._hash = this._getHash();
51511
51514
 
51512
51515
  /**
@@ -51757,6 +51760,10 @@ class VBORenderer {
51757
51760
  this._uSAOParams = program.getLocation("uSAOParams");
51758
51761
  }
51759
51762
 
51763
+ if (this._useAlphaCutoff) {
51764
+ this._alphaCutoffLocation = program.getLocation("materialAlphaCutoff");
51765
+ }
51766
+
51760
51767
  if (scene.logarithmicDepthBufferEnabled) {
51761
51768
  this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
51762
51769
  }
@@ -52094,6 +52101,10 @@ class VBORenderer {
52094
52101
  }
52095
52102
  }
52096
52103
 
52104
+ if (this._useAlphaCutoff) {
52105
+ gl.uniform1f(this._alphaCutoffLocation, textureSet.alphaCutoff);
52106
+ }
52107
+
52097
52108
  if (colorUniform) {
52098
52109
  const colorKey = this._edges ? "edgeColor" : "fillColor";
52099
52110
  const alphaKey = this._edges ? "edgeAlpha" : "fillAlpha";
@@ -52144,8 +52155,8 @@ class VBORenderer {
52144
52155
  */
52145
52156
  class TrianglesBatchingRenderer extends VBORenderer {
52146
52157
 
52147
- constructor(scene, withSAO, {edges = false} = {}) {
52148
- super(scene, withSAO, {instancing: false, edges});
52158
+ constructor(scene, withSAO, {edges = false, useAlphaCutoff = false} = {}) {
52159
+ super(scene, withSAO, {instancing: false, edges, useAlphaCutoff});
52149
52160
  }
52150
52161
 
52151
52162
  _draw(drawCfg) {
@@ -52162,7 +52173,6 @@ class TrianglesBatchingRenderer extends VBORenderer {
52162
52173
  } else {
52163
52174
  const count = frameCtx.pickElementsCount || state.indicesBuf.numItems;
52164
52175
  const offset = frameCtx.pickElementsOffset ? frameCtx.pickElementsOffset * state.indicesBuf.itemByteSize : 0;
52165
-
52166
52176
  gl.drawElements(gl.TRIANGLES, count, state.indicesBuf.itemType, offset);
52167
52177
 
52168
52178
  if (incrementDrawState) {
@@ -54615,6 +54625,7 @@ class TrianglesPickNormalsFlatRenderer$1 extends TrianglesBatchingRenderer {
54615
54625
  /**
54616
54626
  * @private
54617
54627
  */
54628
+
54618
54629
  class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54619
54630
  _getHash() {
54620
54631
  const scene = this._scene;
@@ -54622,11 +54633,10 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54622
54633
  }
54623
54634
 
54624
54635
  drawLayer(frameCtx, layer, renderPass) {
54625
- super.drawLayer(frameCtx, layer, renderPass, {incrementDrawState: true});
54636
+ super.drawLayer(frameCtx, layer, renderPass, { incrementDrawState: true });
54626
54637
  }
54627
54638
 
54628
54639
  _buildVertexShader() {
54629
-
54630
54640
  const scene = this._scene;
54631
54641
  const sectionPlanesState = scene._sectionPlanesState;
54632
54642
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
@@ -54681,6 +54691,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54681
54691
  if (scene.entityOffsetsEnabled) {
54682
54692
  src.push("worldPosition.xyz = worldPosition.xyz + offset;");
54683
54693
  }
54694
+
54684
54695
  src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
54685
54696
  src.push("vViewPosition = viewPosition;");
54686
54697
  src.push("vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, float(color.a) / 255.0);");
@@ -54691,10 +54702,12 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54691
54702
  src.push("vFragDepth = 1.0 + clipPos.w;");
54692
54703
  src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
54693
54704
  }
54705
+
54694
54706
  if (clipping) {
54695
54707
  src.push("vWorldPosition = worldPosition;");
54696
54708
  src.push("vFlags = flags;");
54697
54709
  }
54710
+
54698
54711
  src.push("gl_Position = clipPos;");
54699
54712
  src.push("}");
54700
54713
  src.push("}");
@@ -54707,6 +54720,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54707
54720
  const lightsState = scene._lightsState;
54708
54721
  const sectionPlanesState = scene._sectionPlanesState;
54709
54722
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
54723
+ const useAlphaCutoff = this._useAlphaCutoff;
54710
54724
  const src = [];
54711
54725
  src.push("#version 300 es");
54712
54726
  src.push("// Triangles batching color texture fragment shader");
@@ -54765,6 +54779,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54765
54779
  src.push("uniform vec4 sliceColor;");
54766
54780
  }
54767
54781
  this._addMatricesUniformBlockLines(src);
54782
+
54768
54783
  src.push("uniform vec4 lightAmbient;");
54769
54784
  for (let i = 0, len = lightsState.lights.length; i < len; i++) {
54770
54785
  const light = lightsState.lights[i];
@@ -54784,6 +54799,10 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54784
54799
  }
54785
54800
  }
54786
54801
 
54802
+ if (useAlphaCutoff) {
54803
+ src.push("uniform float materialAlphaCutoff;");
54804
+ }
54805
+
54787
54806
  src.push("in vec4 vViewPosition;");
54788
54807
  src.push("in vec4 vColor;");
54789
54808
  src.push("in vec2 vUV;");
@@ -54851,11 +54870,21 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54851
54870
  }
54852
54871
 
54853
54872
  src.push("vec4 color = vec4((lightAmbient.rgb * lightAmbient.a * newColor.rgb) + (reflectedColor * newColor.rgb), newColor.a);");
54873
+
54874
+ src.push("vec4 sampleColor = texture(uColorMap, vUV);");
54875
+
54876
+ if (useAlphaCutoff) {
54877
+ src.push("if (sampleColor.a < materialAlphaCutoff) {");
54878
+ src.push(" discard;");
54879
+ src.push("}");
54880
+ }
54881
+
54854
54882
  if (gammaOutput) {
54855
- src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
54856
- } else {
54857
- src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
54883
+ src.push("sampleColor = sRGBToLinear(sampleColor);");
54858
54884
  }
54885
+
54886
+ src.push("vec4 colorTexel = color * sampleColor;");
54887
+
54859
54888
  src.push("float opacity = color.a;");
54860
54889
 
54861
54890
  if (this._withSAO) {
@@ -55402,7 +55431,7 @@ class TrianglesSnapRenderer$1 extends VBORenderer{
55402
55431
 
55403
55432
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
55404
55433
  src.push(`if (pickFlag != renderPass) {`);
55405
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
55434
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
55406
55435
  src.push(" } else {");
55407
55436
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
55408
55437
  if (scene.entityOffsetsEnabled) {
@@ -55529,6 +55558,14 @@ class Renderers$1 {
55529
55558
  this._colorTextureRendererWithSAO.destroy();
55530
55559
  this._colorTextureRendererWithSAO = null;
55531
55560
  }
55561
+ if (this._colorTextureRendererAlphaCutoff && (!this._colorTextureRendererAlphaCutoff.getValid())) {
55562
+ this._colorTextureRendererAlphaCutoff.destroy();
55563
+ this._colorTextureRendererAlphaCutoff = null;
55564
+ }
55565
+ if (this._colorTextureRendererWithSAOAlphaCutoff && (!this._colorTextureRendererWithSAOAlphaCutoff.getValid())) {
55566
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
55567
+ this._colorTextureRendererWithSAOAlphaCutoff = null;
55568
+ }
55532
55569
  if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
55533
55570
  this._pbrRenderer.destroy();
55534
55571
  this._pbrRenderer = null;
@@ -55656,6 +55693,20 @@ class Renderers$1 {
55656
55693
  return this._colorTextureRendererWithSAO;
55657
55694
  }
55658
55695
 
55696
+ get colorTextureRendererAlphaCutoff() {
55697
+ if (!this._colorTextureRendererAlphaCutoff) {
55698
+ this._colorTextureRendererAlphaCutoff = new TrianglesColorTextureRenderer$1(this._scene, false, { useAlphaCutoff: true });
55699
+ }
55700
+ return this._colorTextureRendererAlphaCutoff;
55701
+ }
55702
+
55703
+ get colorTextureRendererWithSAOAlphaCutoff() {
55704
+ if (!this._colorTextureRendererWithSAOAlphaCutoff) {
55705
+ this._colorTextureRendererWithSAOAlphaCutoff = new TrianglesColorTextureRenderer$1(this._scene, true, { useAlphaCutoff: true });
55706
+ }
55707
+ return this._colorTextureRendererWithSAOAlphaCutoff;
55708
+ }
55709
+
55659
55710
  get pbrRenderer() {
55660
55711
  if (!this._pbrRenderer) {
55661
55712
  this._pbrRenderer = new TrianglesPBRRenderer$1(this._scene, false);
@@ -55780,6 +55831,12 @@ class Renderers$1 {
55780
55831
  if (this._colorTextureRendererWithSAO) {
55781
55832
  this._colorTextureRendererWithSAO.destroy();
55782
55833
  }
55834
+ if (this._colorTextureRendererAlphaCutoff) {
55835
+ this._colorTextureRendererAlphaCutoff.destroy();
55836
+ }
55837
+ if (this._colorTextureRendererWithSAOAlphaCutoff) {
55838
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
55839
+ }
55783
55840
  if (this._pbrRenderer) {
55784
55841
  this._pbrRenderer.destroy();
55785
55842
  }
@@ -55828,29 +55885,29 @@ class Renderers$1 {
55828
55885
  }
55829
55886
  }
55830
55887
 
55831
- const cachdRenderers$1 = {};
55888
+ const cachedRenderers$6 = {};
55832
55889
 
55833
55890
  /**
55834
55891
  * @private
55835
55892
  */
55836
55893
  function getRenderers$7(scene) {
55837
55894
  const sceneId = scene.id;
55838
- let batchingRenderers = cachdRenderers$1[sceneId];
55839
- if (!batchingRenderers) {
55840
- batchingRenderers = new Renderers$1(scene);
55841
- cachdRenderers$1[sceneId] = batchingRenderers;
55842
- batchingRenderers._compile();
55843
- batchingRenderers.eagerCreateRenders();
55895
+ let renderers = cachedRenderers$6[sceneId];
55896
+ if (!renderers) {
55897
+ renderers = new Renderers$1(scene);
55898
+ cachedRenderers$6[sceneId] = renderers;
55899
+ renderers._compile();
55900
+ renderers.eagerCreateRenders();
55844
55901
  scene.on("compile", () => {
55845
- batchingRenderers._compile();
55846
- batchingRenderers.eagerCreateRenders();
55902
+ renderers._compile();
55903
+ renderers.eagerCreateRenders();
55847
55904
  });
55848
55905
  scene.on("destroyed", () => {
55849
- delete cachdRenderers$1[sceneId];
55850
- batchingRenderers._destroy();
55906
+ delete cachedRenderers$6[sceneId];
55907
+ renderers._destroy();
55851
55908
  });
55852
55909
  }
55853
- return batchingRenderers;
55910
+ return renderers;
55854
55911
  }
55855
55912
 
55856
55913
  let maxDataTextureHeight = 1 << 16;
@@ -57014,14 +57071,21 @@ class VBOBatchingTrianglesLayer {
57014
57071
  return;
57015
57072
  }
57016
57073
  this._updateBackfaceCull(renderFlags, frameCtx);
57074
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
57017
57075
  if (frameCtx.withSAO && this.model.saoEnabled) {
57018
57076
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
57019
57077
  if (this._renderers.pbrRendererWithSAO) {
57020
57078
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57021
57079
  }
57022
57080
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
57023
- if (this._renderers.colorTextureRendererWithSAO) {
57024
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57081
+ if (useAlphaCutoff) {
57082
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
57083
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57084
+ }
57085
+ } else {
57086
+ if (this._renderers.colorTextureRendererWithSAO) {
57087
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57088
+ }
57025
57089
  }
57026
57090
  } else if (this._state.normalsBuf) {
57027
57091
  if (this._renderers.colorRendererWithSAO) {
@@ -57038,8 +57102,14 @@ class VBOBatchingTrianglesLayer {
57038
57102
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57039
57103
  }
57040
57104
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
57041
- if (this._renderers.colorTextureRenderer) {
57042
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57105
+ if (useAlphaCutoff) {
57106
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
57107
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57108
+ }
57109
+ } else {
57110
+ if (this._renderers.colorTextureRenderer) {
57111
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57112
+ }
57043
57113
  }
57044
57114
  } else if (this._state.normalsBuf) {
57045
57115
  if (this._renderers.colorRenderer) {
@@ -57076,8 +57146,15 @@ class VBOBatchingTrianglesLayer {
57076
57146
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57077
57147
  }
57078
57148
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
57079
- if (this._renderers.colorTextureRenderer) {
57080
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57149
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
57150
+ if (useAlphaCutoff) {
57151
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
57152
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57153
+ }
57154
+ } else {
57155
+ if (this._renderers.colorTextureRenderer) {
57156
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57157
+ }
57081
57158
  }
57082
57159
  } else if (this._state.normalsBuf) {
57083
57160
  if (this._renderers.colorRenderer) {
@@ -57421,8 +57498,8 @@ class VBOBatchingTrianglesLayer {
57421
57498
  * @private
57422
57499
  */
57423
57500
  class TrianglesInstancingRenderer extends VBORenderer {
57424
- constructor(scene, withSAO, {edges = false} = {}) {
57425
- super(scene, withSAO, {instancing: true, edges});
57501
+ constructor(scene, withSAO, {edges = false, useAlphaCutoff = false} = {}) {
57502
+ super(scene, withSAO, {instancing: true, edges, useAlphaCutoff});
57426
57503
  }
57427
57504
 
57428
57505
  _draw(drawCfg) {
@@ -57431,13 +57508,14 @@ class TrianglesInstancingRenderer extends VBORenderer {
57431
57508
  const {
57432
57509
  state,
57433
57510
  frameCtx,
57434
- incrementDrawState,
57511
+ incrementDrawState
57435
57512
  } = drawCfg;
57436
57513
 
57437
57514
  if (this._edges) {
57438
57515
  gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
57439
57516
  } else {
57440
57517
  gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
57518
+
57441
57519
  if (incrementDrawState) {
57442
57520
  frameCtx.drawElements++;
57443
57521
  }
@@ -59966,7 +60044,6 @@ class TrianglesPickNormalsFlatRenderer extends TrianglesInstancingRenderer {
59966
60044
  * @private
59967
60045
  */
59968
60046
 
59969
-
59970
60047
  class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59971
60048
  _getHash() {
59972
60049
  const scene = this._scene;
@@ -60035,7 +60112,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60035
60112
  src.push("vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
60036
60113
  src.push("worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
60037
60114
  if (scene.entityOffsetsEnabled) {
60038
- src.push(" worldPosition.xyz = worldPosition.xyz + offset;");
60115
+ src.push("worldPosition.xyz = worldPosition.xyz + offset;");
60039
60116
  }
60040
60117
 
60041
60118
  src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
@@ -60063,11 +60140,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60063
60140
  _buildFragmentShader() {
60064
60141
  const scene = this._scene;
60065
60142
  const gammaOutput = scene.gammaOutput; // If set, then it expects that all textures and colors need to be outputted in premultiplied gamma. Default is false.
60066
- const sectionPlanesState = scene._sectionPlanesState;
60067
60143
  const lightsState = scene._lightsState;
60068
- let i;
60069
- let len;
60144
+ const sectionPlanesState = scene._sectionPlanesState;
60070
60145
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
60146
+ const useAlphaCutoff = this._useAlphaCutoff;
60071
60147
  const src = [];
60072
60148
  src.push("#version 300 es");
60073
60149
  src.push("// Instancing geometry drawing fragment shader");
@@ -60079,6 +60155,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60079
60155
  src.push("precision mediump float;");
60080
60156
  src.push("precision mediump int;");
60081
60157
  src.push("#endif");
60158
+
60082
60159
  if (scene.logarithmicDepthBufferEnabled) {
60083
60160
  src.push("in float isPerspective;");
60084
60161
  src.push("uniform float logDepthBufFC;");
@@ -60127,7 +60204,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60127
60204
  this._addMatricesUniformBlockLines(src);
60128
60205
 
60129
60206
  src.push("uniform vec4 lightAmbient;");
60130
- for (i = 0, len = lightsState.lights.length; i < len; i++) {
60207
+ for (let i = 0, len = lightsState.lights.length; i < len; i++) {
60131
60208
  const light = lightsState.lights[i];
60132
60209
  if (light.type === "ambient") {
60133
60210
  continue;
@@ -60145,6 +60222,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60145
60222
  }
60146
60223
  }
60147
60224
 
60225
+ if (useAlphaCutoff) {
60226
+ src.push("uniform float materialAlphaCutoff;");
60227
+ }
60228
+
60148
60229
  src.push("in vec4 vViewPosition;");
60149
60230
  src.push("in vec4 vColor;");
60150
60231
  src.push("in vec2 vUV;");
@@ -60180,7 +60261,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60180
60261
  src.push("vec3 yTangent = dFdy( vViewPosition.xyz );");
60181
60262
  src.push("vec3 viewNormal = normalize( cross( xTangent, yTangent ) );");
60182
60263
 
60183
- for (i = 0, len = lightsState.lights.length; i < len; i++) {
60264
+ for (let i = 0, len = lightsState.lights.length; i < len; i++) {
60184
60265
  const light = lightsState.lights[i];
60185
60266
  if (light.type === "ambient") {
60186
60267
  continue;
@@ -60206,16 +60287,27 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60206
60287
  } else {
60207
60288
  continue;
60208
60289
  }
60290
+
60209
60291
  src.push("lambertian = max(dot(-viewNormal, viewLightDir), 0.0);");
60210
60292
  src.push("reflectedColor += lambertian * (lightColor" + i + ".rgb * lightColor" + i + ".a);");
60211
60293
  }
60212
60294
 
60213
60295
  src.push("vec4 color = vec4((lightAmbient.rgb * lightAmbient.a * newColor.rgb) + (reflectedColor * newColor.rgb), newColor.a);");
60296
+
60297
+ src.push("vec4 sampleColor = texture(uColorMap, vUV);");
60298
+
60299
+ if (useAlphaCutoff) {
60300
+ src.push("if (sampleColor.a < materialAlphaCutoff) {");
60301
+ src.push(" discard;");
60302
+ src.push("}");
60303
+ }
60304
+
60214
60305
  if (gammaOutput) {
60215
- src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
60216
- } else {
60217
- src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
60306
+ src.push("sampleColor = sRGBToLinear(sampleColor);");
60218
60307
  }
60308
+
60309
+ src.push("vec4 colorTexel = color * sampleColor;");
60310
+
60219
60311
  src.push("float opacity = color.a;");
60220
60312
 
60221
60313
  if (this._withSAO) {
@@ -60227,9 +60319,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60227
60319
  src.push(" float blendFactor = uSAOParams[3];");
60228
60320
  src.push(" vec2 uv = vec2(gl_FragCoord.x / viewportWidth, gl_FragCoord.y / viewportHeight);");
60229
60321
  src.push(" float ambient = smoothstep(blendCutoff, 1.0, unpackRGBToFloat(texture(uOcclusionTexture, uv))) * blendFactor;");
60230
- src.push(" outColor = vec4(newColor.rgb * colorTexel.rgb * ambient, opacity);");
60322
+
60323
+ src.push(" outColor = vec4(colorTexel.rgb * ambient, opacity);");
60231
60324
  } else {
60232
- src.push(" outColor = vec4(newColor.rgb * colorTexel.rgb, opacity);");
60325
+ src.push(" outColor = vec4(colorTexel.rgb, opacity);");
60233
60326
  }
60234
60327
 
60235
60328
  if (gammaOutput) {
@@ -60237,7 +60330,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60237
60330
  }
60238
60331
 
60239
60332
  if (scene.logarithmicDepthBufferEnabled) {
60240
- src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
60333
+ src.push("gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
60241
60334
  }
60242
60335
 
60243
60336
  src.push("}");
@@ -60807,7 +60900,7 @@ class TrianglesSnapRenderer extends VBORenderer {
60807
60900
  // renderPass = PICK
60808
60901
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
60809
60902
  src.push(`if (pickFlag != renderPass) {`);
60810
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
60903
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
60811
60904
  src.push("} else {");
60812
60905
  src.push(" vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
60813
60906
  src.push(" worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
@@ -60927,14 +61020,6 @@ class Renderers {
60927
61020
  this._flatColorRendererWithSAO.destroy();
60928
61021
  this._flatColorRendererWithSAO = null;
60929
61022
  }
60930
- if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
60931
- this._pbrRenderer.destroy();
60932
- this._pbrRenderer = null;
60933
- }
60934
- if (this._pbrRendererWithSAO && (!this._pbrRendererWithSAO.getValid())) {
60935
- this._pbrRendererWithSAO.destroy();
60936
- this._pbrRendererWithSAO = null;
60937
- }
60938
61023
  if (this._colorTextureRenderer && (!this._colorTextureRenderer.getValid())) {
60939
61024
  this._colorTextureRenderer.destroy();
60940
61025
  this._colorTextureRenderer = null;
@@ -60943,6 +61028,22 @@ class Renderers {
60943
61028
  this._colorTextureRendererWithSAO.destroy();
60944
61029
  this._colorTextureRendererWithSAO = null;
60945
61030
  }
61031
+ if (this._colorTextureRendererAlphaCutoff && (!this._colorTextureRendererAlphaCutoff.getValid())) {
61032
+ this._colorTextureRendererAlphaCutoff.destroy();
61033
+ this._colorTextureRendererAlphaCutoff = null;
61034
+ }
61035
+ if (this._colorTextureRendererWithSAOAlphaCutoff && (!this._colorTextureRendererWithSAOAlphaCutoff.getValid())) {
61036
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
61037
+ this._colorTextureRendererWithSAOAlphaCutoff = null;
61038
+ }
61039
+ if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
61040
+ this._pbrRenderer.destroy();
61041
+ this._pbrRenderer = null;
61042
+ }
61043
+ if (this._pbrRendererWithSAO && (!this._pbrRendererWithSAO.getValid())) {
61044
+ this._pbrRendererWithSAO.destroy();
61045
+ this._pbrRendererWithSAO = null;
61046
+ }
60946
61047
  if (this._depthRenderer && (!this._depthRenderer.getValid())) {
60947
61048
  this._depthRenderer.destroy();
60948
61049
  this._depthRenderer = null;
@@ -60975,7 +61076,7 @@ class Renderers {
60975
61076
  this._pickNormalsRenderer.destroy();
60976
61077
  this._pickNormalsRenderer = null;
60977
61078
  }
60978
- if (this._pickNormalsFlatRenderer && (!this._pickNormalsFlatRenderer.getValid())) {
61079
+ if (this._pickNormalsFlatRenderer && this._pickNormalsFlatRenderer.getValid() === false) {
60979
61080
  this._pickNormalsFlatRenderer.destroy();
60980
61081
  this._pickNormalsFlatRenderer = null;
60981
61082
  }
@@ -61048,20 +61149,6 @@ class Renderers {
61048
61149
  return this._flatColorRendererWithSAO;
61049
61150
  }
61050
61151
 
61051
- get pbrRenderer() {
61052
- if (!this._pbrRenderer) {
61053
- this._pbrRenderer = new TrianglesPBRRenderer(this._scene, false);
61054
- }
61055
- return this._pbrRenderer;
61056
- }
61057
-
61058
- get pbrRendererWithSAO() {
61059
- if (!this._pbrRendererWithSAO) {
61060
- this._pbrRendererWithSAO = new TrianglesPBRRenderer(this._scene, true);
61061
- }
61062
- return this._pbrRendererWithSAO;
61063
- }
61064
-
61065
61152
  get colorTextureRenderer() {
61066
61153
  if (!this._colorTextureRenderer) {
61067
61154
  this._colorTextureRenderer = new TrianglesColorTextureRenderer(this._scene, false);
@@ -61076,6 +61163,34 @@ class Renderers {
61076
61163
  return this._colorTextureRendererWithSAO;
61077
61164
  }
61078
61165
 
61166
+ get colorTextureRendererAlphaCutoff() {
61167
+ if (!this._colorTextureRendererAlphaCutoff) {
61168
+ this._colorTextureRendererAlphaCutoff = new TrianglesColorTextureRenderer(this._scene, false, { useAlphaCutoff: true });
61169
+ }
61170
+ return this._colorTextureRendererAlphaCutoff;
61171
+ }
61172
+
61173
+ get colorTextureRendererWithSAOAlphaCutoff() {
61174
+ if (!this._colorTextureRendererWithSAOAlphaCutoff) {
61175
+ this._colorTextureRendererWithSAOAlphaCutoff = new TrianglesColorTextureRenderer(this._scene, true, { useAlphaCutoff: true });
61176
+ }
61177
+ return this._colorTextureRendererWithSAOAlphaCutoff;
61178
+ }
61179
+
61180
+ get pbrRenderer() {
61181
+ if (!this._pbrRenderer) {
61182
+ this._pbrRenderer = new TrianglesPBRRenderer(this._scene, false);
61183
+ }
61184
+ return this._pbrRenderer;
61185
+ }
61186
+
61187
+ get pbrRendererWithSAO() {
61188
+ if (!this._pbrRendererWithSAO) {
61189
+ this._pbrRendererWithSAO = new TrianglesPBRRenderer(this._scene, true);
61190
+ }
61191
+ return this._pbrRendererWithSAO;
61192
+ }
61193
+
61079
61194
  get silhouetteRenderer() {
61080
61195
  if (!this._silhouetteRenderer) {
61081
61196
  this._silhouetteRenderer = new TrianglesSilhouetteRenderer(this._scene);
@@ -61153,13 +61268,6 @@ class Renderers {
61153
61268
  return this._shadowRenderer;
61154
61269
  }
61155
61270
 
61156
- get snapInitRenderer() {
61157
- if (!this._snapInitRenderer) {
61158
- this._snapInitRenderer = new TrianglesSnapInitRenderer(this._scene, false);
61159
- }
61160
- return this._snapInitRenderer;
61161
- }
61162
-
61163
61271
  get snapRenderer() {
61164
61272
  if (!this._snapRenderer) {
61165
61273
  this._snapRenderer = new TrianglesSnapRenderer(this._scene);
@@ -61167,6 +61275,13 @@ class Renderers {
61167
61275
  return this._snapRenderer;
61168
61276
  }
61169
61277
 
61278
+ get snapInitRenderer() {
61279
+ if (!this._snapInitRenderer) {
61280
+ this._snapInitRenderer = new TrianglesSnapInitRenderer(this._scene);
61281
+ }
61282
+ return this._snapInitRenderer;
61283
+ }
61284
+
61170
61285
  _destroy() {
61171
61286
  if (this._colorRenderer) {
61172
61287
  this._colorRenderer.destroy();
@@ -61180,18 +61295,24 @@ class Renderers {
61180
61295
  if (this._flatColorRendererWithSAO) {
61181
61296
  this._flatColorRendererWithSAO.destroy();
61182
61297
  }
61183
- if (this._pbrRenderer) {
61184
- this._pbrRenderer.destroy();
61185
- }
61186
- if (this._pbrRendererWithSAO) {
61187
- this._pbrRendererWithSAO.destroy();
61188
- }
61189
61298
  if (this._colorTextureRenderer) {
61190
61299
  this._colorTextureRenderer.destroy();
61191
61300
  }
61192
61301
  if (this._colorTextureRendererWithSAO) {
61193
61302
  this._colorTextureRendererWithSAO.destroy();
61194
61303
  }
61304
+ if (this._colorTextureRendererAlphaCutoff) {
61305
+ this._colorTextureRendererAlphaCutoff.destroy();
61306
+ }
61307
+ if (this._colorTextureRendererWithSAOAlphaCutoff) {
61308
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
61309
+ }
61310
+ if (this._pbrRenderer) {
61311
+ this._pbrRenderer.destroy();
61312
+ }
61313
+ if (this._pbrRendererWithSAO) {
61314
+ this._pbrRendererWithSAO.destroy();
61315
+ }
61195
61316
  if (this._depthRenderer) {
61196
61317
  this._depthRenderer.destroy();
61197
61318
  }
@@ -61241,22 +61362,22 @@ const cachedRenderers$5 = {};
61241
61362
  */
61242
61363
  function getRenderers$6(scene) {
61243
61364
  const sceneId = scene.id;
61244
- let instancingRenderers = cachedRenderers$5[sceneId];
61245
- if (!instancingRenderers) {
61246
- instancingRenderers = new Renderers(scene);
61247
- cachedRenderers$5[sceneId] = instancingRenderers;
61248
- instancingRenderers._compile();
61249
- instancingRenderers.eagerCreateRenders();
61365
+ let renderers = cachedRenderers$5[sceneId];
61366
+ if (!renderers) {
61367
+ renderers = new Renderers(scene);
61368
+ cachedRenderers$5[sceneId] = renderers;
61369
+ renderers._compile();
61370
+ renderers.eagerCreateRenders();
61250
61371
  scene.on("compile", () => {
61251
- instancingRenderers._compile();
61252
- instancingRenderers.eagerCreateRenders();
61372
+ renderers._compile();
61373
+ renderers.eagerCreateRenders();
61253
61374
  });
61254
61375
  scene.on("destroyed", () => {
61255
61376
  delete cachedRenderers$5[sceneId];
61256
- instancingRenderers._destroy();
61377
+ renderers._destroy();
61257
61378
  });
61258
61379
  }
61259
- return instancingRenderers;
61380
+ return renderers;
61260
61381
  }
61261
61382
 
61262
61383
  const tempUint8Vec4$2 = new Uint8Array(4);
@@ -62038,14 +62159,21 @@ class VBOInstancingTrianglesLayer {
62038
62159
  return;
62039
62160
  }
62040
62161
  this._updateBackfaceCull(renderFlags, frameCtx);
62162
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
62041
62163
  if (frameCtx.withSAO && this.model.saoEnabled) {
62042
62164
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
62043
62165
  if (this._renderers.pbrRendererWithSAO) {
62044
62166
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62045
62167
  }
62046
62168
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
62047
- if (this._renderers.colorTextureRendererWithSAO) {
62048
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62169
+ if (useAlphaCutoff) {
62170
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
62171
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62172
+ }
62173
+ } else {
62174
+ if (this._renderers.colorTextureRendererWithSAO) {
62175
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62176
+ }
62049
62177
  }
62050
62178
  } else if (this._state.normalsBuf) {
62051
62179
  if (this._renderers.colorRendererWithSAO) {
@@ -62061,8 +62189,14 @@ class VBOInstancingTrianglesLayer {
62061
62189
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62062
62190
  }
62063
62191
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
62064
- if (this._renderers.colorTextureRenderer) {
62065
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62192
+ if (useAlphaCutoff) {
62193
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
62194
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62195
+ }
62196
+ } else {
62197
+ if (this._renderers.colorTextureRenderer) {
62198
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62199
+ }
62066
62200
  }
62067
62201
  } else if (this._state.normalsBuf) {
62068
62202
  if (this._renderers.colorRenderer) {
@@ -63237,7 +63371,7 @@ class VBOBatchingLinesSnapRenderer extends VBORenderer{
63237
63371
 
63238
63372
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
63239
63373
  src.push(`if (pickFlag != renderPass) {`);
63240
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
63374
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
63241
63375
  src.push(" } else {");
63242
63376
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
63243
63377
  if (scene.entityOffsetsEnabled) {
@@ -64979,7 +65113,7 @@ class VBOInstancingLinesSnapRenderer extends VBORenderer {
64979
65113
  // renderPass = PICK
64980
65114
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
64981
65115
  src.push(`if (pickFlag != renderPass) {`);
64982
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
65116
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
64983
65117
  src.push("} else {");
64984
65118
  src.push(" vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
64985
65119
  src.push(" worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
@@ -75746,6 +75880,14 @@ class DTXTrianglesSnapRenderer {
75746
75880
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
75747
75881
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
75748
75882
 
75883
+ // flags.w = NOT_RENDERED | PICK
75884
+ // renderPass = PICK
75885
+
75886
+ src.push(`if (int(flags.w) != renderPass) {`);
75887
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
75888
+ src.push(" return;"); // Cull vertex
75889
+ src.push("}");
75890
+
75749
75891
  src.push("{");
75750
75892
 
75751
75893
  // get vertex base
@@ -76161,6 +76303,14 @@ class DTXTrianglesSnapInitRenderer {
76161
76303
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
76162
76304
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
76163
76305
 
76306
+ // flags.w = NOT_RENDERED | PICK
76307
+ // renderPass = PICK
76308
+
76309
+ src.push(`if (int(flags.w) != renderPass) {`);
76310
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
76311
+ src.push(" return;"); // Cull vertex
76312
+ src.push("}");
76313
+
76164
76314
  src.push("{");
76165
76315
 
76166
76316
  // get color
@@ -80553,6 +80703,11 @@ class SceneModelTextureSet {
80553
80703
  */
80554
80704
  this.colorTexture = cfg.colorTexture;
80555
80705
 
80706
+ /**
80707
+ * The alpha cutoff [float]
80708
+ */
80709
+ this.alphaCutoff = cfg.alphaCutoff;
80710
+
80556
80711
  /**
80557
80712
  * The metallic-roughness texture.
80558
80713
  * @type {SceneModelTexture|*}
@@ -85109,6 +85264,7 @@ class SceneModel extends Component {
85109
85264
  id: textureSetId,
85110
85265
  model: this,
85111
85266
  colorTexture,
85267
+ alphaCutoff: cfg.alphaCutoff,
85112
85268
  metallicRoughnessTexture,
85113
85269
  normalsTexture,
85114
85270
  emissiveTexture,
@@ -85542,6 +85698,14 @@ class SceneModel extends Component {
85542
85698
  return this._createMesh(cfg);
85543
85699
  }
85544
85700
 
85701
+ _createDefaultIndices(numIndices) {
85702
+ const indices = [];
85703
+ for (let i = 0; i < numIndices; i++) {
85704
+ indices.push(i);
85705
+ }
85706
+ return indices;
85707
+ }
85708
+
85545
85709
  _createMesh(cfg) {
85546
85710
  const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);
85547
85711
  mesh.pickId = this.scene._renderer.getPickID(mesh);
@@ -101591,8 +101755,6 @@ class MetaScene {
101591
101755
  * @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.
101592
101756
  * @param {Object} metaModelData Data for the {@link MetaModel}.
101593
101757
  * @param {Object} [options] Options for creating the {@link MetaModel}.
101594
- * @param {Object} [options.includeTypes] When provided, only create {@link MetaObject}s with types in this list.
101595
- * @param {Object} [options.excludeTypes] When provided, never create {@link MetaObject}s with types in this list.
101596
101758
  * @param {Boolean} [options.globalizeObjectIds=false] Whether to globalize each {@link MetaObject#id}. Set this ````true```` when you need to load multiple instances of the same meta model, to avoid ID clashes between the meta objects in the different instances.
101597
101759
  * @returns {MetaModel} The new MetaModel.
101598
101760
  */
@@ -117578,40 +117740,6 @@ class GLTFSceneModelLoader {
117578
117740
  }
117579
117741
  }
117580
117742
 
117581
- function getMetaModelCorrections(metaModelJSON) {
117582
- const eachRootStats = {};
117583
- const eachChildRoot = {};
117584
- const metaObjects = metaModelJSON.metaObjects || [];
117585
- const metaObjectsMap = {};
117586
- for (let i = 0, len = metaObjects.length; i < len; i++) {
117587
- const metaObject = metaObjects[i];
117588
- metaObjectsMap[metaObject.id] = metaObject;
117589
- }
117590
- for (let i = 0, len = metaObjects.length; i < len; i++) {
117591
- const metaObject = metaObjects[i];
117592
- if (metaObject.parent !== undefined && metaObject.parent !== null) {
117593
- const metaObjectParent = metaObjectsMap[metaObject.parent];
117594
- if (metaObject.type === metaObjectParent.type) {
117595
- let rootMetaObject = metaObjectParent;
117596
- while (rootMetaObject.parent && metaObjectsMap[rootMetaObject.parent].type === rootMetaObject.type) {
117597
- rootMetaObject = metaObjectsMap[rootMetaObject.parent];
117598
- }
117599
- const rootStats = eachRootStats[rootMetaObject.id] || (eachRootStats[rootMetaObject.id] = {
117600
- numChildren: 0,
117601
- countChildren: 0
117602
- });
117603
- rootStats.numChildren++;
117604
- eachChildRoot[metaObject.id] = rootMetaObject;
117605
- }
117606
- }
117607
- }
117608
- return {
117609
- metaObjectsMap,
117610
- eachRootStats,
117611
- eachChildRoot
117612
- };
117613
- }
117614
-
117615
117743
  function loadGLTF(plugin, src, metaModelJSON, options, sceneModel, ok, error) {
117616
117744
  const spinner = plugin.viewer.scene.canvas.spinner;
117617
117745
  spinner.processes++;
@@ -117653,7 +117781,9 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
117653
117781
  const ctx = {
117654
117782
  src: src,
117655
117783
  entityId: options.entityId,
117656
- metaModelCorrections: metaModelJSON ? getMetaModelCorrections(metaModelJSON) : null,
117784
+ metaModelJSON,
117785
+ autoMetaModel: options.autoMetaModel,
117786
+ metaObjects: [],
117657
117787
  loadBuffer: options.loadBuffer,
117658
117788
  basePath: options.basePath,
117659
117789
  handlenode: options.handlenode,
@@ -117672,8 +117802,20 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
117672
117802
  };
117673
117803
  loadTextures(ctx);
117674
117804
  loadMaterials(ctx);
117805
+ if (options.autoMetaModel) {
117806
+ ctx.metaObjects.push({
117807
+ id: sceneModel.id,
117808
+ type: "Default",
117809
+ name: sceneModel.id
117810
+ });
117811
+ }
117675
117812
  loadDefaultScene(ctx);
117676
117813
  sceneModel.finalize();
117814
+ if (options.autoMetaModel) {
117815
+ plugin.viewer.metaScene.createMetaModel(sceneModel.id, {
117816
+ metaObjects: ctx.metaObjects
117817
+ });
117818
+ }
117677
117819
  spinner.processes--;
117678
117820
  ok();
117679
117821
  });
@@ -117802,23 +117944,17 @@ function loadTextureSet(ctx, material) {
117802
117944
  if (material.emissiveTexture) {
117803
117945
  textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;
117804
117946
  }
117805
- // const alphaMode = material.alphaMode;
117806
- // switch (alphaMode) {
117807
- // case "NORMAL_OPAQUE":
117808
- // materialCfg.alphaMode = "opaque";
117809
- // break;
117810
- // case "MASK":
117811
- // materialCfg.alphaMode = "mask";
117812
- // break;
117813
- // case "BLEND":
117814
- // materialCfg.alphaMode = "blend";
117815
- // break;
117816
- // default:
117817
- // }
117818
- // const alphaCutoff = material.alphaCutoff;
117819
- // if (alphaCutoff !== undefined) {
117820
- // materialCfg.alphaCutoff = alphaCutoff;
117821
- // }
117947
+
117948
+ switch (material.alphaMode) {
117949
+ case "OPAQUE":
117950
+ break;
117951
+ case "MASK":
117952
+ const alphaCutoff = material.alphaCutoff;
117953
+ // Default from the spec https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-material
117954
+ textureSetCfg.alphaCutoff = (alphaCutoff !== undefined) ? alphaCutoff : 0.5;
117955
+ break;
117956
+ }
117957
+
117822
117958
  const metallicPBR = material.pbrMetallicRoughness;
117823
117959
  if (material.pbrMetallicRoughness) {
117824
117960
  const pbrMetallicRoughness = material.pbrMetallicRoughness;
@@ -117864,7 +118000,7 @@ function loadMaterialAttributes(ctx, material) { // Substitute RGBA for material
117864
118000
  opacity: 1,
117865
118001
  metallic: 0,
117866
118002
  roughness: 1,
117867
- doubleSided : true
118003
+ doubleSided: true
117868
118004
  };
117869
118005
  if (extensions) {
117870
118006
  const specularPBR = extensions["KHR_materials_pbrSpecularGlossiness"];
@@ -117938,9 +118074,22 @@ function loadScene(ctx, scene) {
117938
118074
  const node = nodes[i];
117939
118075
  countMeshUsage(ctx, node);
117940
118076
  }
117941
- for (let i = 0, len = nodes.length; i < len; i++) {
118077
+ for (let i = 0, len = nodes.length; i < len && !ctx.nodesHaveNames; i++) {
117942
118078
  const node = nodes[i];
117943
- loadNode(ctx, node, 0, null);
118079
+ if (testIfNodesHaveNames(node)) {
118080
+ ctx.nodesHaveNames = true;
118081
+ }
118082
+ }
118083
+ if (!ctx.nodesHaveNames) {
118084
+ for (let i = 0, len = nodes.length; i < len; i++) {
118085
+ const node = nodes[i];
118086
+ parseNodesWithoutNames(ctx, node, 0, null);
118087
+ }
118088
+ } else {
118089
+ for (let i = 0, len = nodes.length; i < len; i++) {
118090
+ const node = nodes[i];
118091
+ parseNodesWithNames(ctx, node, 0, null);
118092
+ }
117944
118093
  }
117945
118094
  }
117946
118095
 
@@ -117962,10 +118111,131 @@ function countMeshUsage(ctx, node) {
117962
118111
  }
117963
118112
  }
117964
118113
 
117965
- const deferredMeshIds = [];
118114
+ function testIfNodesHaveNames(node) {
118115
+ if (node.name) {
118116
+ return true;
118117
+ }
118118
+ if (node.children) {
118119
+ const children = node.children;
118120
+ for (let i = 0, len = children.length; i < len; i++) {
118121
+ const childNode = children[i];
118122
+ if (testIfNodesHaveNames(childNode)) {
118123
+ return true;
118124
+ }
118125
+ }
118126
+ }
118127
+ return false;
118128
+ }
117966
118129
 
117967
- function loadNode(ctx, node, depth, matrix) {
117968
- ctx.gltfData;
118130
+ /**
118131
+ * Parses a glTF node hierarchy that is known to NOT contain "name" attributes on the nodes.
118132
+ * Create a SceneMesh for each mesh primitive, and a single SceneObject.
118133
+ */
118134
+ const parseNodesWithoutNames = (function () {
118135
+ const meshIds = [];
118136
+ return function (ctx, node, depth, matrix, parentNode) {
118137
+ matrix = parseNodeMatrix(node, matrix);
118138
+ if (node.mesh) {
118139
+ parseNodeMesh(node, ctx, matrix, meshIds);
118140
+ }
118141
+ if (node.children) {
118142
+ const children = node.children;
118143
+ for (let i = 0, len = children.length; i < len; i++) {
118144
+ const childNode = children[i];
118145
+ parseNodesWithoutNames(ctx, childNode, depth + 1, matrix, node);
118146
+ }
118147
+ }
118148
+ if (depth === 0) {
118149
+ let entityId = "entity-" + ctx.nextId++;
118150
+ if (meshIds && meshIds.length > 0) {
118151
+ ctx.sceneModel.createEntity({
118152
+ id: entityId,
118153
+ meshIds,
118154
+ isObject: true
118155
+ });
118156
+ if (ctx.autoMetaModel) {
118157
+ ctx.metaObjects.push({
118158
+ id: entityId,
118159
+ type: "Default",
118160
+ name: entityId,
118161
+ parent: ctx.sceneModel.id
118162
+ });
118163
+ }
118164
+ meshIds.length = 0;
118165
+ }
118166
+ }
118167
+ }
118168
+ })();
118169
+
118170
+ const parseNodesWithNames = (function () {
118171
+
118172
+ const objectIdStack = [];
118173
+ const meshIdsStack = [];
118174
+ let meshIds = [];
118175
+
118176
+ return function (ctx, node, depth, matrix) {
118177
+ matrix = parseNodeMatrix(node, matrix);
118178
+ if (meshIds && node.mesh) {
118179
+ parseNodeMesh(node, ctx, matrix, meshIds);
118180
+ }
118181
+
118182
+ if (node.name) {
118183
+ meshIds = [];
118184
+ let entityId = node.name;
118185
+ if (!!entityId && ctx.sceneModel.objects[entityId]) ;
118186
+ while (!entityId || ctx.sceneModel.objects[entityId]) {
118187
+ entityId = "entity-" + ctx.nextId++;
118188
+ }
118189
+ objectIdStack.push(entityId);
118190
+ meshIdsStack.push(meshIds);
118191
+ }
118192
+
118193
+ if (node.children) {
118194
+ const children = node.children;
118195
+ for (let i = 0, len = children.length; i < len; i++) {
118196
+ const childNode = children[i];
118197
+ parseNodesWithNames(ctx, childNode, depth + 1, matrix);
118198
+ }
118199
+ }
118200
+
118201
+ // Post-order visit scene node
118202
+
118203
+ const nodeName = node.name;
118204
+ if ((nodeName !== undefined && nodeName !== null) || depth === 0) {
118205
+ let entityId = objectIdStack.pop();
118206
+ if (!entityId) { // For when there are no nodes with names
118207
+ entityId = "entity-" + ctx.nextId++;
118208
+ }
118209
+ let entityMeshIds = meshIdsStack.pop();
118210
+ if (meshIds && meshIds.length > 0) {
118211
+ ctx.sceneModel.createEntity({
118212
+ id: entityId,
118213
+ meshIds: entityMeshIds,
118214
+ isObject: true
118215
+ });
118216
+ if (ctx.autoMetaModel) {
118217
+ ctx.metaObjects.push({
118218
+ id: entityId,
118219
+ type: "Default",
118220
+ name: entityId,
118221
+ parent: ctx.sceneModel.id
118222
+ });
118223
+ }
118224
+ }
118225
+ meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;
118226
+ }
118227
+ };
118228
+ })();
118229
+
118230
+
118231
+ /**
118232
+ * Parses transform at the given glTF node.
118233
+ *
118234
+ * @param node the glTF node
118235
+ * @param matrix Transfor matrix from parent nodes
118236
+ * @returns {*} Transform matrix for the node
118237
+ */
118238
+ function parseNodeMatrix(node, matrix) {
117969
118239
  let localMatrix;
117970
118240
  if (node.matrix) {
117971
118241
  localMatrix = node.matrix;
@@ -117999,171 +118269,96 @@ function loadNode(ctx, node, depth, matrix) {
117999
118269
  matrix = localMatrix;
118000
118270
  }
118001
118271
  }
118272
+ return matrix;
118273
+ }
118002
118274
 
118003
- const sceneModel = ctx.sceneModel;
118004
- if (node.mesh) {
118005
- const mesh = node.mesh;
118006
- if (ctx.handlenode) {
118007
- const actions = {};
118008
- if (!ctx.handlenode(ctx.sceneModel.id, node, actions)) {
118009
- return;
118010
- }
118011
- if (actions.createEntity) ;
118012
- }
118013
- const worldMatrix = matrix ? matrix.slice() : math.identityMat4();
118014
- const numPrimitives = mesh.primitives.length;
118015
-
118016
- if (numPrimitives > 0) {
118017
-
118018
- for (let i = 0; i < numPrimitives; i++) {
118019
-
118020
- const primitive = mesh.primitives[i];
118021
- if (primitive.mode < 4) {
118022
- continue;
118023
- }
118024
-
118025
- const meshCfg = {
118026
- id: sceneModel.id + "." + ctx.numObjects++
118027
- };
118028
-
118029
- const material = primitive.material;
118030
- if (material) {
118031
- meshCfg.textureSetId = material._textureSetId;
118032
- meshCfg.color = material._attributes.color;
118033
- meshCfg.opacity = material._attributes.opacity;
118034
- meshCfg.metallic = material._attributes.metallic;
118035
- meshCfg.roughness = material._attributes.roughness;
118036
- } else {
118037
- meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);
118038
- meshCfg.opacity = 1.0;
118039
- }
118040
-
118041
- const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));
118042
-
118043
- switch (primitive.mode) {
118044
- case 0: // POINTS
118045
- meshCfg.primitive = "points";
118046
- break;
118047
- case 1: // LINES
118048
- meshCfg.primitive = "lines";
118049
- break;
118050
- case 2: // LINE_LOOP
118051
- meshCfg.primitive = "lines";
118052
- break;
118053
- case 3: // LINE_STRIP
118054
- meshCfg.primitive = "lines";
118055
- break;
118056
- case 4: // TRIANGLES
118057
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118058
- break;
118059
- case 5: // TRIANGLE_STRIP
118060
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118061
- break;
118062
- case 6: // TRIANGLE_FAN
118063
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118064
- break;
118065
- default:
118066
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118067
- }
118068
-
118069
- const POSITION = primitive.attributes.POSITION;
118070
- if (!POSITION) {
118071
- continue;
118072
- }
118073
- meshCfg.localPositions = POSITION.value;
118074
- meshCfg.positions = new Float64Array(meshCfg.localPositions.length);
118075
-
118076
- if (primitive.attributes.NORMAL) {
118077
- meshCfg.normals = primitive.attributes.NORMAL.value;
118078
- }
118079
-
118080
- if (primitive.attributes.TEXCOORD_0) {
118081
- meshCfg.uv = primitive.attributes.TEXCOORD_0.value;
118082
- }
118083
-
118084
- if (primitive.indices) {
118085
- meshCfg.indices = primitive.indices.value;
118086
- }
118087
-
118088
- math.transformPositions3(worldMatrix, meshCfg.localPositions, meshCfg.positions);
118089
- const origin = math.vec3();
118090
- const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
118091
- if (rtcNeeded) {
118092
- meshCfg.origin = origin;
118093
- }
118094
-
118095
- sceneModel.createMesh(meshCfg);
118096
- deferredMeshIds.push(meshCfg.id);
118097
- }
118098
- }
118099
- }
118100
-
118101
- if (node.children) {
118102
- const children = node.children;
118103
- for (let i = 0, len = children.length; i < len; i++) {
118104
- const childNode = children[i];
118105
- loadNode(ctx, childNode, depth + 1, matrix);
118106
- }
118275
+ /**
118276
+ * Parses primitives referenced by the mesh belonging to the given node, creating XKTMeshes in the XKTModel.
118277
+ *
118278
+ * @param node glTF node
118279
+ * @param ctx Parsing context
118280
+ * @param matrix Matrix for the XKTMeshes
118281
+ * @param meshIds returns IDs of the new XKTMeshes
118282
+ */
118283
+ function parseNodeMesh(node, ctx, matrix, meshIds) {
118284
+ const mesh = node.mesh;
118285
+ if (!mesh) {
118286
+ return;
118107
118287
  }
118108
-
118109
- // Post-order visit scene node
118110
-
118111
- if (ctx.entityId) {
118112
- if (depth ===0) {
118113
- sceneModel.createEntity({
118114
- id: ctx.entityId,
118115
- meshIds: deferredMeshIds,
118116
- isObject: true
118117
- });
118118
- deferredMeshIds.length = 0;
118119
- }
118120
- } else {
118121
- const nodeName = node.name;
118122
- if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {
118123
- if (nodeName === undefined || nodeName === null) {
118124
- ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);
118288
+ const numPrimitives = mesh.primitives.length;
118289
+ if (numPrimitives > 0) {
118290
+ for (let i = 0; i < numPrimitives; i++) {
118291
+ const primitive = mesh.primitives[i];
118292
+ if (primitive.mode < 4) {
118293
+ continue;
118125
118294
  }
118126
- let entityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)
118127
- // if (!!entityId && sceneModel.entities[entityId]) {
118128
- // ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${nodeName} - will randomly-generating an object ID in XKT`);
118129
- // }
118130
- // while (!entityId || sceneModel.entities[entityId]) {
118131
- // entityId = "entity-" + ctx.nextId++;
118132
- // }
118133
- if (ctx.metaModelCorrections) {
118134
- // Merging meshes into XKTObjects that map to metaobjects
118135
- const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[entityId];
118136
- if (rootMetaObject) {
118137
- const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];
118138
- rootMetaObjectStats.countChildren++;
118139
- if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {
118140
- sceneModel.createEntity({
118141
- id: rootMetaObject.id,
118142
- meshIds: deferredMeshIds,
118143
- isObject: true
118144
- });
118145
- deferredMeshIds.length = 0;
118146
- }
118147
- } else {
118148
- const metaObject = ctx.metaModelCorrections.metaObjectsMap[entityId];
118149
- if (metaObject) {
118150
- sceneModel.createEntity({
118151
- id: entityId,
118152
- meshIds: deferredMeshIds,
118153
- isObject: true
118154
- });
118155
- deferredMeshIds.length = 0;
118156
- }
118157
- }
118295
+ const meshCfg = {
118296
+ id: ctx.sceneModel.id + "." + ctx.numObjects++
118297
+ };
118298
+ const material = primitive.material;
118299
+ if (material) {
118300
+ meshCfg.textureSetId = material._textureSetId;
118301
+ meshCfg.color = material._attributes.color;
118302
+ meshCfg.opacity = material._attributes.opacity;
118303
+ meshCfg.metallic = material._attributes.metallic;
118304
+ meshCfg.roughness = material._attributes.roughness;
118158
118305
  } else {
118159
- // Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
118160
- sceneModel.createEntity({
118161
- id: entityId,
118162
- meshIds: deferredMeshIds,
118163
- isObject: true
118164
- });
118165
- deferredMeshIds.length = 0;
118306
+ meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);
118307
+ meshCfg.opacity = 1.0;
118308
+ }
118309
+ const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));
118310
+ switch (primitive.mode) {
118311
+ case 0: // POINTS
118312
+ meshCfg.primitive = "points";
118313
+ break;
118314
+ case 1: // LINES
118315
+ meshCfg.primitive = "lines";
118316
+ break;
118317
+ case 2: // LINE_LOOP
118318
+ meshCfg.primitive = "lines";
118319
+ break;
118320
+ case 3: // LINE_STRIP
118321
+ meshCfg.primitive = "lines";
118322
+ break;
118323
+ case 4: // TRIANGLES
118324
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118325
+ break;
118326
+ case 5: // TRIANGLE_STRIP
118327
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118328
+ break;
118329
+ case 6: // TRIANGLE_FAN
118330
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118331
+ break;
118332
+ default:
118333
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118334
+ }
118335
+ const POSITION = primitive.attributes.POSITION;
118336
+ if (!POSITION) {
118337
+ continue;
118338
+ }
118339
+ meshCfg.localPositions = POSITION.value;
118340
+ meshCfg.positions = new Float64Array(meshCfg.localPositions.length);
118341
+ if (primitive.attributes.NORMAL) {
118342
+ meshCfg.normals = primitive.attributes.NORMAL.value;
118343
+ }
118344
+ if (primitive.attributes.TEXCOORD_0) {
118345
+ meshCfg.uv = primitive.attributes.TEXCOORD_0.value;
118166
118346
  }
118347
+ if (primitive.indices) {
118348
+ meshCfg.indices = primitive.indices.value;
118349
+ }
118350
+ if (matrix) {
118351
+ math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
118352
+ } else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
118353
+ meshCfg.positions.set(meshCfg.localPositions);
118354
+ }
118355
+ const origin = math.vec3();
118356
+ const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
118357
+ if (rtcNeeded) {
118358
+ meshCfg.origin = origin;
118359
+ }
118360
+ ctx.sceneModel.createMesh(meshCfg);
118361
+ meshIds.push(meshCfg.id);
118167
118362
  }
118168
118363
  }
118169
118364
  }
@@ -118490,8 +118685,6 @@ class GLTFLoaderPlugin extends Plugin {
118490
118685
  * @param {String} [params.metaModelSrc] Path to an optional metadata file, as an alternative to the ````metaModelJSON```` parameter.
118491
118686
  * @param {*} [params.metaModelJSON] JSON model metadata, as an alternative to the ````metaModelSrc```` parameter.
118492
118687
  * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
118493
- * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
118494
- * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
118495
118688
  * @param {Boolean} [params.edges=false] Whether or not xeokit renders the model with edges emphasized.
118496
118689
  * @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.
118497
118690
  * @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.
@@ -118507,150 +118700,47 @@ class GLTFLoaderPlugin extends Plugin {
118507
118700
  * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
118508
118701
  * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
118509
118702
  * primitives. Only works while {@link DTX#enabled} is also ````true````.
118510
- * @param {String} [params.entityId] When supplied, causes the entire model to be loaded into a single {@link Entity} that gets this ID.
118703
+ * @param {Boolean} [params.autoMetaModel] When supplied, creates a default MetaModel with a single MetaObject.
118511
118704
  * @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}
118512
118705
  */
118513
118706
  load(params = {}) {
118514
-
118515
118707
  if (params.id && this.viewer.scene.components[params.id]) {
118516
118708
  this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
118517
118709
  delete params.id;
118518
118710
  }
118519
-
118520
118711
  const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
118521
118712
  isModel: true,
118522
118713
  dtxEnabled: params.dtxEnabled
118523
118714
  }));
118524
-
118525
118715
  const modelId = sceneModel.id; // In case ID was auto-generated
118526
-
118527
118716
  if (!params.src && !params.gltf) {
118528
118717
  this.error("load() param expected: src or gltf");
118529
118718
  return sceneModel; // Return new empty model
118530
118719
  }
118531
-
118532
118720
  if (params.metaModelSrc || params.metaModelJSON) {
118533
-
118534
- const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
118535
-
118536
118721
  const processMetaModelJSON = (metaModelJSON) => {
118537
-
118538
- this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {
118539
- includeTypes: params.includeTypes,
118540
- excludeTypes: params.excludeTypes
118541
- });
118542
-
118722
+ this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {});
118543
118723
  this.viewer.scene.canvas.spinner.processes--;
118544
-
118545
- let includeTypes;
118546
- if (params.includeTypes) {
118547
- includeTypes = {};
118548
- for (let i = 0, len = params.includeTypes.length; i < len; i++) {
118549
- includeTypes[params.includeTypes[i]] = true;
118550
- }
118551
- }
118552
- if (params.excludeTypes) {
118553
- if (!includeTypes) {
118554
- includeTypes = {};
118555
- }
118556
- for (let i = 0, len = params.excludeTypes.length; i < len; i++) {
118557
- includeTypes[params.excludeTypes[i]] = true;
118558
- }
118559
- }
118560
-
118561
- params.readableGeometry = false;
118562
-
118563
- params.handleGLTFNode = (modelId, glTFNode, actions) => {
118564
-
118565
- const name = glTFNode.name;
118566
-
118567
- if (!name) {
118568
- return true; // Continue descending this node subtree
118569
- }
118570
-
118571
- const nodeId = name;
118572
- const metaObject = this.viewer.metaScene.metaObjects[nodeId];
118573
- const type = (metaObject ? metaObject.type : "DEFAULT") || "DEFAULT";
118574
-
118575
- actions.createEntity = {
118576
- id: nodeId,
118577
- isObject: true // Registers the Entity in Scene#objects
118578
- };
118579
-
118580
- const props = objectDefaults[type];
118581
-
118582
- if (props) { // Set Entity's initial rendering state for recognized type
118583
-
118584
- if (props.visible === false) {
118585
- actions.createEntity.visible = false;
118586
- }
118587
-
118588
- if (props.colorize) {
118589
- actions.createEntity.colorize = props.colorize;
118590
- }
118591
-
118592
- if (props.pickable === false) {
118593
- actions.createEntity.pickable = false;
118594
- }
118595
-
118596
- if (props.opacity !== undefined && props.opacity !== null) {
118597
- actions.createEntity.opacity = props.opacity;
118598
- }
118599
- }
118600
-
118601
- return true; // Continue descending this glTF node subtree
118602
- };
118603
-
118604
118724
  if (params.src) {
118605
118725
  this._sceneModelLoader.load(this, params.src, metaModelJSON, params, sceneModel);
118606
118726
  } else {
118607
118727
  this._sceneModelLoader.parse(this, params.gltf, metaModelJSON, params, sceneModel);
118608
118728
  }
118609
118729
  };
118610
-
118611
118730
  if (params.metaModelSrc) {
118612
-
118613
118731
  const metaModelSrc = params.metaModelSrc;
118614
-
118615
118732
  this.viewer.scene.canvas.spinner.processes++;
118616
-
118617
118733
  this._dataSource.getMetaModel(metaModelSrc, (metaModelJSON) => {
118618
-
118619
118734
  this.viewer.scene.canvas.spinner.processes--;
118620
-
118621
118735
  processMetaModelJSON(metaModelJSON);
118622
-
118623
118736
  }, (errMsg) => {
118624
118737
  this.error(`load(): Failed to load model metadata for model '${modelId} from '${metaModelSrc}' - ${errMsg}`);
118625
118738
  this.viewer.scene.canvas.spinner.processes--;
118626
118739
  });
118627
-
118628
118740
  } else if (params.metaModelJSON) {
118629
-
118630
118741
  processMetaModelJSON(params.metaModelJSON);
118631
118742
  }
118632
-
118633
118743
  } else {
118634
-
118635
- params.handleGLTFNode = (modelId, glTFNode, actions) => {
118636
-
118637
- const name = glTFNode.name;
118638
-
118639
- if (!name) {
118640
- return true; // Continue descending this node subtree
118641
- }
118642
-
118643
- const id = name;
118644
-
118645
- actions.createEntity = { // Create an Entity for this glTF scene node
118646
- id: id,
118647
- isObject: true // Registers the Entity in Scene#objects
118648
- };
118649
-
118650
- return true; // Continue descending this glTF node subtree
118651
- };
118652
-
118653
-
118654
118744
  if (params.src) {
118655
118745
  this._sceneModelLoader.load(this, params.src, null, params, sceneModel);
118656
118746
  } else {
@@ -126986,7 +127076,7 @@ class TreeViewPlugin extends Plugin {
126986
127076
  this._nodeNodes[buildingNode.nodeId] = buildingNode;
126987
127077
  } else if (metaObjectType === "IfcBuildingStorey") {
126988
127078
  if (!buildingNode) {
126989
- this.error("Failed to build storeys hierarchy for model '" + this.metaModel.id + "' - model does not have an IfcBuilding object, or is not an IFC model");
127079
+ this.error("Failed to build storeys hierarchy for model - model does not have an IfcBuilding object, or is not an IFC model");
126990
127080
  return;
126991
127081
  }
126992
127082
  storeyNode = {
@@ -139173,49 +139263,126 @@ class DotBIMLoaderPlugin extends Plugin {
139173
139263
 
139174
139264
  const dbMeshId = element.mesh_id;
139175
139265
 
139176
- parseDBMesh(dbMeshId);
139177
-
139178
- const meshId = `${objectId}-mesh`;
139179
139266
  const vector = element.vector;
139180
139267
  const rotation = element.rotation;
139181
139268
  const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
139182
-
139183
139269
  let visible = true;
139184
139270
  let pickable = true;
139185
- let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
139186
- let opacity = element.color ? element.color.a / 255 : 1.0;
139187
139271
 
139188
- if (props) {
139189
- if (props.visible === false) {
139190
- visible = false;
139191
- }
139192
- if (props.pickable === false) {
139193
- pickable = false;
139194
- }
139195
- if (props.colorize) {
139196
- color = props.colorize;
139197
- }
139198
- if (props.opacity !== undefined && props.opacity !== null) {
139199
- opacity = props.opacity;
139272
+ if (element.face_colors === undefined) {
139273
+
139274
+ parseDBMesh(dbMeshId);
139275
+
139276
+ const meshId = `${objectId}-mesh`;
139277
+
139278
+ let color = element.color ? [element.color.r / 255.0, element.color.g / 255.0, element.color.b / 255.0] : [1, 1, 1];
139279
+ let opacity = element.color ? element.color.a / 255.0 : 1.0;
139280
+
139281
+ if (props) {
139282
+ if (props.visible === false) {
139283
+ visible = false;
139284
+ }
139285
+ if (props.pickable === false) {
139286
+ pickable = false;
139287
+ }
139288
+ if (props.colorize) {
139289
+ color = props.colorize;
139290
+ }
139291
+ if (props.opacity !== undefined && props.opacity !== null) {
139292
+ opacity = props.opacity;
139293
+ }
139200
139294
  }
139295
+
139296
+ sceneModel.createMesh({
139297
+ id: meshId,
139298
+ geometryId: dbMeshId,
139299
+ color: color,
139300
+ opacity: opacity,
139301
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
139302
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
139303
+ });
139304
+
139305
+ sceneModel.createEntity({
139306
+ id: objectId,
139307
+ meshIds: [meshId],
139308
+ visible: visible,
139309
+ pickable: pickable,
139310
+ isObject: true
139311
+ });
139201
139312
  }
139313
+ else {
139314
+ let faceColors = element.face_colors;
139315
+ let coloredTrianglesDictionary = {};
139316
+ let currentTriangleIndicesCount = 0;
139317
+ let dbMesh = fileData.meshes[element.mesh_id];
139318
+ for (let i = 0, len = faceColors.length; i < len; i+=4) {
139319
+ let faceColor = [faceColors[i], faceColors[i+1], faceColors[i+2], faceColors[i+3]];
139320
+ if (coloredTrianglesDictionary[faceColor] === undefined) {
139321
+ coloredTrianglesDictionary[faceColor] = [];
139322
+ }
139323
+ let indexForPoint0 = dbMesh.indices[currentTriangleIndicesCount];
139324
+ let x0 = dbMesh.coordinates[indexForPoint0*3];
139325
+ let y0 = dbMesh.coordinates[indexForPoint0*3+1];
139326
+ let z0 = dbMesh.coordinates[indexForPoint0*3+2];
139327
+ let indexForPoint1 = dbMesh.indices[currentTriangleIndicesCount+1];
139328
+ let x1 = dbMesh.coordinates[indexForPoint1*3];
139329
+ let y1 = dbMesh.coordinates[indexForPoint1*3+1];
139330
+ let z1 = dbMesh.coordinates[indexForPoint1*3+2];
139331
+ let indexForPoint2 = dbMesh.indices[currentTriangleIndicesCount+2];
139332
+ let x2 = dbMesh.coordinates[indexForPoint2*3];
139333
+ let y2 = dbMesh.coordinates[indexForPoint2*3+1];
139334
+ let z2 = dbMesh.coordinates[indexForPoint2*3+2];
139335
+ coloredTrianglesDictionary[faceColor].push(x0, y0, z0, x1, y1, z1, x2, y2, z2);
139336
+
139337
+ currentTriangleIndicesCount += 3;
139338
+ }
139339
+ let meshIds = [];
139340
+ for (const [faceColor, trianglesCoordinates] of Object.entries(coloredTrianglesDictionary)) {
139341
+ sceneModel.createGeometry({
139342
+ id: `${dbMeshId}-${faceColor}`,
139343
+ primitive: "triangles",
139344
+ positions: trianglesCoordinates,
139345
+ indices: [...Array(trianglesCoordinates.length).keys()]
139346
+ });
139347
+ const meshId = `${objectId}-mesh-${faceColor}`;
139348
+ const faceColorArray = faceColor.split(',').map(Number);
139202
139349
 
139203
- sceneModel.createMesh({
139204
- id: meshId,
139205
- geometryId: dbMeshId,
139206
- color,
139207
- opacity,
139208
- quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
139209
- position: vector ? [vector.x, vector.y, vector.z] : undefined
139210
- });
139350
+ let color = [faceColorArray[0] / 255.0, faceColorArray[1] / 255.0, faceColorArray[2] / 255.0];
139351
+ let opacity = faceColorArray[3] / 255.0;
139211
139352
 
139212
- sceneModel.createEntity({
139213
- id: objectId,
139214
- meshIds: [meshId],
139215
- visible,
139216
- pickable,
139217
- isObject: true
139218
- });
139353
+ if (props) {
139354
+ if (props.visible === false) {
139355
+ visible = false;
139356
+ }
139357
+ if (props.pickable === false) {
139358
+ pickable = false;
139359
+ }
139360
+ if (props.colorize) {
139361
+ color = props.colorize;
139362
+ }
139363
+ if (props.opacity !== undefined && props.opacity !== null) {
139364
+ opacity = props.opacity;
139365
+ }
139366
+ }
139367
+
139368
+ sceneModel.createMesh({
139369
+ id: meshId,
139370
+ geometryId: `${dbMeshId}-${faceColor}`,
139371
+ color: color,
139372
+ opacity: opacity,
139373
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
139374
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
139375
+ });
139376
+ meshIds.push(meshId);
139377
+ }
139378
+ sceneModel.createEntity({
139379
+ id: objectId,
139380
+ meshIds: meshIds,
139381
+ visible: visible,
139382
+ pickable: pickable,
139383
+ isObject: true
139384
+ });
139385
+ }
139219
139386
 
139220
139387
  for (let infoKey in info) {
139221
139388
  let properties;