@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
@@ -17471,7 +17471,7 @@ class OcclusionLayer {
17471
17471
  for (let i = 0; i < this.numMarkers; i++) {
17472
17472
  if (this.markerList[i]) {
17473
17473
  const marker = this.markerList[i];
17474
- const worldPos = marker.worldPos;
17474
+ const worldPos = marker.rtcPos;
17475
17475
  this.positions[j++] = worldPos[0];
17476
17476
  this.positions[j++] = worldPos[1];
17477
17477
  this.positions[j++] = worldPos[2];
@@ -17913,10 +17913,7 @@ class OcclusionTester {
17913
17913
  continue;
17914
17914
  }
17915
17915
 
17916
- // The `origin` has been changed from `occlusionLayer.origin` to `[ 0, 0, 0 ]`
17917
- // because OcclusionLayer markers' transformation is being applied through the
17918
- // OcclusionLayer::positions array. See XEOK-33
17919
- const origin = [ 0, 0, 0 ];
17916
+ const origin = occlusionLayer.origin;
17920
17917
 
17921
17918
  gl.uniformMatrix4fv(this._uViewMatrix, false, createRTCViewMat(camera.viewMatrix, origin));
17922
17919
 
@@ -20507,6 +20504,8 @@ const Renderer$1 = function (scene, options) {
20507
20504
  // result 1) regular hi-precision world position
20508
20505
 
20509
20506
  let worldPos = null;
20507
+ let worldNormal = null;
20508
+ let pickable = null;
20510
20509
 
20511
20510
  const middleX = snapRadiusInPixels;
20512
20511
  const middleY = snapRadiusInPixels;
@@ -20524,7 +20523,7 @@ const Renderer$1 = function (scene, options) {
20524
20523
  pickResultMiddleXY[1] * scale[1] + origin[1],
20525
20524
  pickResultMiddleXY[2] * scale[2] + origin[2],
20526
20525
  ];
20527
- math.normalizeVec3([
20526
+ worldNormal = math.normalizeVec3([
20528
20527
  pickNormalResultMiddleXY[0] / math.MAX_INT,
20529
20528
  pickNormalResultMiddleXY[1] / math.MAX_INT,
20530
20529
  pickNormalResultMiddleXY[2] / math.MAX_INT,
@@ -20536,7 +20535,7 @@ const Renderer$1 = function (scene, options) {
20536
20535
  + (pickPickableResultMiddleXY[2] << 16)
20537
20536
  + (pickPickableResultMiddleXY[3] << 24);
20538
20537
 
20539
- pickIDs.items[pickID];
20538
+ pickable = pickIDs.items[pickID];
20540
20539
  }
20541
20540
 
20542
20541
  // result 2) hi-precision snapped (to vertex/edge) world position
@@ -20633,13 +20632,16 @@ const Renderer$1 = function (scene, options) {
20633
20632
  }
20634
20633
 
20635
20634
  const snappedEntity = (snappedPickable && snappedPickable.delegatePickedEntity) ? snappedPickable.delegatePickedEntity() : snappedPickable;
20635
+ if (!snappedEntity && pickable) {
20636
+ pickable = pickable.delegatePickedEntity ? pickable.delegatePickedEntity() : pickable;
20637
+ }
20636
20638
 
20637
20639
  pickResult.reset();
20638
20640
  pickResult.snappedToEdge = (snapType === "edge");
20639
20641
  pickResult.snappedToVertex = (snapType === "vertex");
20640
- pickResult.worldPos = snappedWorldPos;
20641
- pickResult.worldNormal = snappedWorldNormal;
20642
- pickResult.entity = snappedEntity;
20642
+ pickResult.worldPos = snappedWorldPos || worldPos;
20643
+ pickResult.worldNormal = snappedWorldNormal || worldNormal;
20644
+ pickResult.entity = snappedEntity || pickable;
20643
20645
  pickResult.canvasPos = canvasPos || scene.camera.projectWorldPos(worldPos || snappedWorldPos);
20644
20646
  pickResult.snappedCanvasPos = snappedCanvasPos || canvasPos;
20645
20647
 
@@ -51506,11 +51508,12 @@ const tempMat4a$r = math.mat4();
51506
51508
  * @private
51507
51509
  */
51508
51510
  class VBORenderer {
51509
- constructor(scene, withSAO = false, {instancing = false, edges = false} = {}) {
51511
+ constructor(scene, withSAO = false, {instancing = false, edges = false, useAlphaCutoff = false} = {}) {
51510
51512
  this._scene = scene;
51511
51513
  this._withSAO = withSAO;
51512
51514
  this._instancing = instancing;
51513
51515
  this._edges = edges;
51516
+ this._useAlphaCutoff = useAlphaCutoff;
51514
51517
  this._hash = this._getHash();
51515
51518
 
51516
51519
  /**
@@ -51761,6 +51764,10 @@ class VBORenderer {
51761
51764
  this._uSAOParams = program.getLocation("uSAOParams");
51762
51765
  }
51763
51766
 
51767
+ if (this._useAlphaCutoff) {
51768
+ this._alphaCutoffLocation = program.getLocation("materialAlphaCutoff");
51769
+ }
51770
+
51764
51771
  if (scene.logarithmicDepthBufferEnabled) {
51765
51772
  this._uLogDepthBufFC = program.getLocation("logDepthBufFC");
51766
51773
  }
@@ -52098,6 +52105,10 @@ class VBORenderer {
52098
52105
  }
52099
52106
  }
52100
52107
 
52108
+ if (this._useAlphaCutoff) {
52109
+ gl.uniform1f(this._alphaCutoffLocation, textureSet.alphaCutoff);
52110
+ }
52111
+
52101
52112
  if (colorUniform) {
52102
52113
  const colorKey = this._edges ? "edgeColor" : "fillColor";
52103
52114
  const alphaKey = this._edges ? "edgeAlpha" : "fillAlpha";
@@ -52148,8 +52159,8 @@ class VBORenderer {
52148
52159
  */
52149
52160
  class TrianglesBatchingRenderer extends VBORenderer {
52150
52161
 
52151
- constructor(scene, withSAO, {edges = false} = {}) {
52152
- super(scene, withSAO, {instancing: false, edges});
52162
+ constructor(scene, withSAO, {edges = false, useAlphaCutoff = false} = {}) {
52163
+ super(scene, withSAO, {instancing: false, edges, useAlphaCutoff});
52153
52164
  }
52154
52165
 
52155
52166
  _draw(drawCfg) {
@@ -52166,7 +52177,6 @@ class TrianglesBatchingRenderer extends VBORenderer {
52166
52177
  } else {
52167
52178
  const count = frameCtx.pickElementsCount || state.indicesBuf.numItems;
52168
52179
  const offset = frameCtx.pickElementsOffset ? frameCtx.pickElementsOffset * state.indicesBuf.itemByteSize : 0;
52169
-
52170
52180
  gl.drawElements(gl.TRIANGLES, count, state.indicesBuf.itemType, offset);
52171
52181
 
52172
52182
  if (incrementDrawState) {
@@ -54619,6 +54629,7 @@ class TrianglesPickNormalsFlatRenderer$1 extends TrianglesBatchingRenderer {
54619
54629
  /**
54620
54630
  * @private
54621
54631
  */
54632
+
54622
54633
  class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54623
54634
  _getHash() {
54624
54635
  const scene = this._scene;
@@ -54626,11 +54637,10 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54626
54637
  }
54627
54638
 
54628
54639
  drawLayer(frameCtx, layer, renderPass) {
54629
- super.drawLayer(frameCtx, layer, renderPass, {incrementDrawState: true});
54640
+ super.drawLayer(frameCtx, layer, renderPass, { incrementDrawState: true });
54630
54641
  }
54631
54642
 
54632
54643
  _buildVertexShader() {
54633
-
54634
54644
  const scene = this._scene;
54635
54645
  const sectionPlanesState = scene._sectionPlanesState;
54636
54646
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
@@ -54685,6 +54695,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54685
54695
  if (scene.entityOffsetsEnabled) {
54686
54696
  src.push("worldPosition.xyz = worldPosition.xyz + offset;");
54687
54697
  }
54698
+
54688
54699
  src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
54689
54700
  src.push("vViewPosition = viewPosition;");
54690
54701
  src.push("vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, float(color.a) / 255.0);");
@@ -54695,10 +54706,12 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54695
54706
  src.push("vFragDepth = 1.0 + clipPos.w;");
54696
54707
  src.push("isPerspective = float (isPerspectiveMatrix(projMatrix));");
54697
54708
  }
54709
+
54698
54710
  if (clipping) {
54699
54711
  src.push("vWorldPosition = worldPosition;");
54700
54712
  src.push("vFlags = flags;");
54701
54713
  }
54714
+
54702
54715
  src.push("gl_Position = clipPos;");
54703
54716
  src.push("}");
54704
54717
  src.push("}");
@@ -54711,6 +54724,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54711
54724
  const lightsState = scene._lightsState;
54712
54725
  const sectionPlanesState = scene._sectionPlanesState;
54713
54726
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
54727
+ const useAlphaCutoff = this._useAlphaCutoff;
54714
54728
  const src = [];
54715
54729
  src.push("#version 300 es");
54716
54730
  src.push("// Triangles batching color texture fragment shader");
@@ -54769,6 +54783,7 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54769
54783
  src.push("uniform vec4 sliceColor;");
54770
54784
  }
54771
54785
  this._addMatricesUniformBlockLines(src);
54786
+
54772
54787
  src.push("uniform vec4 lightAmbient;");
54773
54788
  for (let i = 0, len = lightsState.lights.length; i < len; i++) {
54774
54789
  const light = lightsState.lights[i];
@@ -54788,6 +54803,10 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54788
54803
  }
54789
54804
  }
54790
54805
 
54806
+ if (useAlphaCutoff) {
54807
+ src.push("uniform float materialAlphaCutoff;");
54808
+ }
54809
+
54791
54810
  src.push("in vec4 vViewPosition;");
54792
54811
  src.push("in vec4 vColor;");
54793
54812
  src.push("in vec2 vUV;");
@@ -54855,11 +54874,21 @@ class TrianglesColorTextureRenderer$1 extends TrianglesBatchingRenderer {
54855
54874
  }
54856
54875
 
54857
54876
  src.push("vec4 color = vec4((lightAmbient.rgb * lightAmbient.a * newColor.rgb) + (reflectedColor * newColor.rgb), newColor.a);");
54877
+
54878
+ src.push("vec4 sampleColor = texture(uColorMap, vUV);");
54879
+
54880
+ if (useAlphaCutoff) {
54881
+ src.push("if (sampleColor.a < materialAlphaCutoff) {");
54882
+ src.push(" discard;");
54883
+ src.push("}");
54884
+ }
54885
+
54858
54886
  if (gammaOutput) {
54859
- src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
54860
- } else {
54861
- src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
54887
+ src.push("sampleColor = sRGBToLinear(sampleColor);");
54862
54888
  }
54889
+
54890
+ src.push("vec4 colorTexel = color * sampleColor;");
54891
+
54863
54892
  src.push("float opacity = color.a;");
54864
54893
 
54865
54894
  if (this._withSAO) {
@@ -55406,7 +55435,7 @@ class TrianglesSnapRenderer$1 extends VBORenderer{
55406
55435
 
55407
55436
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
55408
55437
  src.push(`if (pickFlag != renderPass) {`);
55409
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
55438
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
55410
55439
  src.push(" } else {");
55411
55440
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
55412
55441
  if (scene.entityOffsetsEnabled) {
@@ -55533,6 +55562,14 @@ class Renderers$1 {
55533
55562
  this._colorTextureRendererWithSAO.destroy();
55534
55563
  this._colorTextureRendererWithSAO = null;
55535
55564
  }
55565
+ if (this._colorTextureRendererAlphaCutoff && (!this._colorTextureRendererAlphaCutoff.getValid())) {
55566
+ this._colorTextureRendererAlphaCutoff.destroy();
55567
+ this._colorTextureRendererAlphaCutoff = null;
55568
+ }
55569
+ if (this._colorTextureRendererWithSAOAlphaCutoff && (!this._colorTextureRendererWithSAOAlphaCutoff.getValid())) {
55570
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
55571
+ this._colorTextureRendererWithSAOAlphaCutoff = null;
55572
+ }
55536
55573
  if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
55537
55574
  this._pbrRenderer.destroy();
55538
55575
  this._pbrRenderer = null;
@@ -55660,6 +55697,20 @@ class Renderers$1 {
55660
55697
  return this._colorTextureRendererWithSAO;
55661
55698
  }
55662
55699
 
55700
+ get colorTextureRendererAlphaCutoff() {
55701
+ if (!this._colorTextureRendererAlphaCutoff) {
55702
+ this._colorTextureRendererAlphaCutoff = new TrianglesColorTextureRenderer$1(this._scene, false, { useAlphaCutoff: true });
55703
+ }
55704
+ return this._colorTextureRendererAlphaCutoff;
55705
+ }
55706
+
55707
+ get colorTextureRendererWithSAOAlphaCutoff() {
55708
+ if (!this._colorTextureRendererWithSAOAlphaCutoff) {
55709
+ this._colorTextureRendererWithSAOAlphaCutoff = new TrianglesColorTextureRenderer$1(this._scene, true, { useAlphaCutoff: true });
55710
+ }
55711
+ return this._colorTextureRendererWithSAOAlphaCutoff;
55712
+ }
55713
+
55663
55714
  get pbrRenderer() {
55664
55715
  if (!this._pbrRenderer) {
55665
55716
  this._pbrRenderer = new TrianglesPBRRenderer$1(this._scene, false);
@@ -55784,6 +55835,12 @@ class Renderers$1 {
55784
55835
  if (this._colorTextureRendererWithSAO) {
55785
55836
  this._colorTextureRendererWithSAO.destroy();
55786
55837
  }
55838
+ if (this._colorTextureRendererAlphaCutoff) {
55839
+ this._colorTextureRendererAlphaCutoff.destroy();
55840
+ }
55841
+ if (this._colorTextureRendererWithSAOAlphaCutoff) {
55842
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
55843
+ }
55787
55844
  if (this._pbrRenderer) {
55788
55845
  this._pbrRenderer.destroy();
55789
55846
  }
@@ -55832,29 +55889,29 @@ class Renderers$1 {
55832
55889
  }
55833
55890
  }
55834
55891
 
55835
- const cachdRenderers$1 = {};
55892
+ const cachedRenderers$6 = {};
55836
55893
 
55837
55894
  /**
55838
55895
  * @private
55839
55896
  */
55840
55897
  function getRenderers$7(scene) {
55841
55898
  const sceneId = scene.id;
55842
- let batchingRenderers = cachdRenderers$1[sceneId];
55843
- if (!batchingRenderers) {
55844
- batchingRenderers = new Renderers$1(scene);
55845
- cachdRenderers$1[sceneId] = batchingRenderers;
55846
- batchingRenderers._compile();
55847
- batchingRenderers.eagerCreateRenders();
55899
+ let renderers = cachedRenderers$6[sceneId];
55900
+ if (!renderers) {
55901
+ renderers = new Renderers$1(scene);
55902
+ cachedRenderers$6[sceneId] = renderers;
55903
+ renderers._compile();
55904
+ renderers.eagerCreateRenders();
55848
55905
  scene.on("compile", () => {
55849
- batchingRenderers._compile();
55850
- batchingRenderers.eagerCreateRenders();
55906
+ renderers._compile();
55907
+ renderers.eagerCreateRenders();
55851
55908
  });
55852
55909
  scene.on("destroyed", () => {
55853
- delete cachdRenderers$1[sceneId];
55854
- batchingRenderers._destroy();
55910
+ delete cachedRenderers$6[sceneId];
55911
+ renderers._destroy();
55855
55912
  });
55856
55913
  }
55857
- return batchingRenderers;
55914
+ return renderers;
55858
55915
  }
55859
55916
 
55860
55917
  let maxDataTextureHeight = 1 << 16;
@@ -57018,14 +57075,21 @@ class VBOBatchingTrianglesLayer {
57018
57075
  return;
57019
57076
  }
57020
57077
  this._updateBackfaceCull(renderFlags, frameCtx);
57078
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
57021
57079
  if (frameCtx.withSAO && this.model.saoEnabled) {
57022
57080
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
57023
57081
  if (this._renderers.pbrRendererWithSAO) {
57024
57082
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57025
57083
  }
57026
57084
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
57027
- if (this._renderers.colorTextureRendererWithSAO) {
57028
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57085
+ if (useAlphaCutoff) {
57086
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
57087
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57088
+ }
57089
+ } else {
57090
+ if (this._renderers.colorTextureRendererWithSAO) {
57091
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57092
+ }
57029
57093
  }
57030
57094
  } else if (this._state.normalsBuf) {
57031
57095
  if (this._renderers.colorRendererWithSAO) {
@@ -57042,8 +57106,14 @@ class VBOBatchingTrianglesLayer {
57042
57106
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57043
57107
  }
57044
57108
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
57045
- if (this._renderers.colorTextureRenderer) {
57046
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57109
+ if (useAlphaCutoff) {
57110
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
57111
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57112
+ }
57113
+ } else {
57114
+ if (this._renderers.colorTextureRenderer) {
57115
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
57116
+ }
57047
57117
  }
57048
57118
  } else if (this._state.normalsBuf) {
57049
57119
  if (this._renderers.colorRenderer) {
@@ -57080,8 +57150,15 @@ class VBOBatchingTrianglesLayer {
57080
57150
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57081
57151
  }
57082
57152
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
57083
- if (this._renderers.colorTextureRenderer) {
57084
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57153
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
57154
+ if (useAlphaCutoff) {
57155
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
57156
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57157
+ }
57158
+ } else {
57159
+ if (this._renderers.colorTextureRenderer) {
57160
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_TRANSPARENT);
57161
+ }
57085
57162
  }
57086
57163
  } else if (this._state.normalsBuf) {
57087
57164
  if (this._renderers.colorRenderer) {
@@ -57425,8 +57502,8 @@ class VBOBatchingTrianglesLayer {
57425
57502
  * @private
57426
57503
  */
57427
57504
  class TrianglesInstancingRenderer extends VBORenderer {
57428
- constructor(scene, withSAO, {edges = false} = {}) {
57429
- super(scene, withSAO, {instancing: true, edges});
57505
+ constructor(scene, withSAO, {edges = false, useAlphaCutoff = false} = {}) {
57506
+ super(scene, withSAO, {instancing: true, edges, useAlphaCutoff});
57430
57507
  }
57431
57508
 
57432
57509
  _draw(drawCfg) {
@@ -57435,13 +57512,14 @@ class TrianglesInstancingRenderer extends VBORenderer {
57435
57512
  const {
57436
57513
  state,
57437
57514
  frameCtx,
57438
- incrementDrawState,
57515
+ incrementDrawState
57439
57516
  } = drawCfg;
57440
57517
 
57441
57518
  if (this._edges) {
57442
57519
  gl.drawElementsInstanced(gl.LINES, state.edgeIndicesBuf.numItems, state.edgeIndicesBuf.itemType, 0, state.numInstances);
57443
57520
  } else {
57444
57521
  gl.drawElementsInstanced(gl.TRIANGLES, state.indicesBuf.numItems, state.indicesBuf.itemType, 0, state.numInstances);
57522
+
57445
57523
  if (incrementDrawState) {
57446
57524
  frameCtx.drawElements++;
57447
57525
  }
@@ -59970,7 +60048,6 @@ class TrianglesPickNormalsFlatRenderer extends TrianglesInstancingRenderer {
59970
60048
  * @private
59971
60049
  */
59972
60050
 
59973
-
59974
60051
  class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
59975
60052
  _getHash() {
59976
60053
  const scene = this._scene;
@@ -60039,7 +60116,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60039
60116
  src.push("vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
60040
60117
  src.push("worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
60041
60118
  if (scene.entityOffsetsEnabled) {
60042
- src.push(" worldPosition.xyz = worldPosition.xyz + offset;");
60119
+ src.push("worldPosition.xyz = worldPosition.xyz + offset;");
60043
60120
  }
60044
60121
 
60045
60122
  src.push("vec4 viewPosition = viewMatrix * worldPosition; ");
@@ -60067,11 +60144,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60067
60144
  _buildFragmentShader() {
60068
60145
  const scene = this._scene;
60069
60146
  const gammaOutput = scene.gammaOutput; // If set, then it expects that all textures and colors need to be outputted in premultiplied gamma. Default is false.
60070
- const sectionPlanesState = scene._sectionPlanesState;
60071
60147
  const lightsState = scene._lightsState;
60072
- let i;
60073
- let len;
60148
+ const sectionPlanesState = scene._sectionPlanesState;
60074
60149
  const clipping = sectionPlanesState.getNumAllocatedSectionPlanes() > 0;
60150
+ const useAlphaCutoff = this._useAlphaCutoff;
60075
60151
  const src = [];
60076
60152
  src.push("#version 300 es");
60077
60153
  src.push("// Instancing geometry drawing fragment shader");
@@ -60083,6 +60159,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60083
60159
  src.push("precision mediump float;");
60084
60160
  src.push("precision mediump int;");
60085
60161
  src.push("#endif");
60162
+
60086
60163
  if (scene.logarithmicDepthBufferEnabled) {
60087
60164
  src.push("in float isPerspective;");
60088
60165
  src.push("uniform float logDepthBufFC;");
@@ -60131,7 +60208,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60131
60208
  this._addMatricesUniformBlockLines(src);
60132
60209
 
60133
60210
  src.push("uniform vec4 lightAmbient;");
60134
- for (i = 0, len = lightsState.lights.length; i < len; i++) {
60211
+ for (let i = 0, len = lightsState.lights.length; i < len; i++) {
60135
60212
  const light = lightsState.lights[i];
60136
60213
  if (light.type === "ambient") {
60137
60214
  continue;
@@ -60149,6 +60226,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60149
60226
  }
60150
60227
  }
60151
60228
 
60229
+ if (useAlphaCutoff) {
60230
+ src.push("uniform float materialAlphaCutoff;");
60231
+ }
60232
+
60152
60233
  src.push("in vec4 vViewPosition;");
60153
60234
  src.push("in vec4 vColor;");
60154
60235
  src.push("in vec2 vUV;");
@@ -60184,7 +60265,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60184
60265
  src.push("vec3 yTangent = dFdy( vViewPosition.xyz );");
60185
60266
  src.push("vec3 viewNormal = normalize( cross( xTangent, yTangent ) );");
60186
60267
 
60187
- for (i = 0, len = lightsState.lights.length; i < len; i++) {
60268
+ for (let i = 0, len = lightsState.lights.length; i < len; i++) {
60188
60269
  const light = lightsState.lights[i];
60189
60270
  if (light.type === "ambient") {
60190
60271
  continue;
@@ -60210,16 +60291,27 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60210
60291
  } else {
60211
60292
  continue;
60212
60293
  }
60294
+
60213
60295
  src.push("lambertian = max(dot(-viewNormal, viewLightDir), 0.0);");
60214
60296
  src.push("reflectedColor += lambertian * (lightColor" + i + ".rgb * lightColor" + i + ".a);");
60215
60297
  }
60216
60298
 
60217
60299
  src.push("vec4 color = vec4((lightAmbient.rgb * lightAmbient.a * newColor.rgb) + (reflectedColor * newColor.rgb), newColor.a);");
60300
+
60301
+ src.push("vec4 sampleColor = texture(uColorMap, vUV);");
60302
+
60303
+ if (useAlphaCutoff) {
60304
+ src.push("if (sampleColor.a < materialAlphaCutoff) {");
60305
+ src.push(" discard;");
60306
+ src.push("}");
60307
+ }
60308
+
60218
60309
  if (gammaOutput) {
60219
- src.push("vec4 colorTexel = color * sRGBToLinear(texture(uColorMap, vUV));");
60220
- } else {
60221
- src.push("vec4 colorTexel = color * texture(uColorMap, vUV);");
60310
+ src.push("sampleColor = sRGBToLinear(sampleColor);");
60222
60311
  }
60312
+
60313
+ src.push("vec4 colorTexel = color * sampleColor;");
60314
+
60223
60315
  src.push("float opacity = color.a;");
60224
60316
 
60225
60317
  if (this._withSAO) {
@@ -60231,9 +60323,10 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60231
60323
  src.push(" float blendFactor = uSAOParams[3];");
60232
60324
  src.push(" vec2 uv = vec2(gl_FragCoord.x / viewportWidth, gl_FragCoord.y / viewportHeight);");
60233
60325
  src.push(" float ambient = smoothstep(blendCutoff, 1.0, unpackRGBToFloat(texture(uOcclusionTexture, uv))) * blendFactor;");
60234
- src.push(" outColor = vec4(newColor.rgb * colorTexel.rgb * ambient, opacity);");
60326
+
60327
+ src.push(" outColor = vec4(colorTexel.rgb * ambient, opacity);");
60235
60328
  } else {
60236
- src.push(" outColor = vec4(newColor.rgb * colorTexel.rgb, opacity);");
60329
+ src.push(" outColor = vec4(colorTexel.rgb, opacity);");
60237
60330
  }
60238
60331
 
60239
60332
  if (gammaOutput) {
@@ -60241,7 +60334,7 @@ class TrianglesColorTextureRenderer extends TrianglesInstancingRenderer {
60241
60334
  }
60242
60335
 
60243
60336
  if (scene.logarithmicDepthBufferEnabled) {
60244
- src.push(" gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
60337
+ src.push("gl_FragDepth = isPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;");
60245
60338
  }
60246
60339
 
60247
60340
  src.push("}");
@@ -60811,7 +60904,7 @@ class TrianglesSnapRenderer extends VBORenderer {
60811
60904
  // renderPass = PICK
60812
60905
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
60813
60906
  src.push(`if (pickFlag != renderPass) {`);
60814
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
60907
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
60815
60908
  src.push("} else {");
60816
60909
  src.push(" vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
60817
60910
  src.push(" worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
@@ -60931,14 +61024,6 @@ class Renderers {
60931
61024
  this._flatColorRendererWithSAO.destroy();
60932
61025
  this._flatColorRendererWithSAO = null;
60933
61026
  }
60934
- if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
60935
- this._pbrRenderer.destroy();
60936
- this._pbrRenderer = null;
60937
- }
60938
- if (this._pbrRendererWithSAO && (!this._pbrRendererWithSAO.getValid())) {
60939
- this._pbrRendererWithSAO.destroy();
60940
- this._pbrRendererWithSAO = null;
60941
- }
60942
61027
  if (this._colorTextureRenderer && (!this._colorTextureRenderer.getValid())) {
60943
61028
  this._colorTextureRenderer.destroy();
60944
61029
  this._colorTextureRenderer = null;
@@ -60947,6 +61032,22 @@ class Renderers {
60947
61032
  this._colorTextureRendererWithSAO.destroy();
60948
61033
  this._colorTextureRendererWithSAO = null;
60949
61034
  }
61035
+ if (this._colorTextureRendererAlphaCutoff && (!this._colorTextureRendererAlphaCutoff.getValid())) {
61036
+ this._colorTextureRendererAlphaCutoff.destroy();
61037
+ this._colorTextureRendererAlphaCutoff = null;
61038
+ }
61039
+ if (this._colorTextureRendererWithSAOAlphaCutoff && (!this._colorTextureRendererWithSAOAlphaCutoff.getValid())) {
61040
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
61041
+ this._colorTextureRendererWithSAOAlphaCutoff = null;
61042
+ }
61043
+ if (this._pbrRenderer && (!this._pbrRenderer.getValid())) {
61044
+ this._pbrRenderer.destroy();
61045
+ this._pbrRenderer = null;
61046
+ }
61047
+ if (this._pbrRendererWithSAO && (!this._pbrRendererWithSAO.getValid())) {
61048
+ this._pbrRendererWithSAO.destroy();
61049
+ this._pbrRendererWithSAO = null;
61050
+ }
60950
61051
  if (this._depthRenderer && (!this._depthRenderer.getValid())) {
60951
61052
  this._depthRenderer.destroy();
60952
61053
  this._depthRenderer = null;
@@ -60979,7 +61080,7 @@ class Renderers {
60979
61080
  this._pickNormalsRenderer.destroy();
60980
61081
  this._pickNormalsRenderer = null;
60981
61082
  }
60982
- if (this._pickNormalsFlatRenderer && (!this._pickNormalsFlatRenderer.getValid())) {
61083
+ if (this._pickNormalsFlatRenderer && this._pickNormalsFlatRenderer.getValid() === false) {
60983
61084
  this._pickNormalsFlatRenderer.destroy();
60984
61085
  this._pickNormalsFlatRenderer = null;
60985
61086
  }
@@ -61052,20 +61153,6 @@ class Renderers {
61052
61153
  return this._flatColorRendererWithSAO;
61053
61154
  }
61054
61155
 
61055
- get pbrRenderer() {
61056
- if (!this._pbrRenderer) {
61057
- this._pbrRenderer = new TrianglesPBRRenderer(this._scene, false);
61058
- }
61059
- return this._pbrRenderer;
61060
- }
61061
-
61062
- get pbrRendererWithSAO() {
61063
- if (!this._pbrRendererWithSAO) {
61064
- this._pbrRendererWithSAO = new TrianglesPBRRenderer(this._scene, true);
61065
- }
61066
- return this._pbrRendererWithSAO;
61067
- }
61068
-
61069
61156
  get colorTextureRenderer() {
61070
61157
  if (!this._colorTextureRenderer) {
61071
61158
  this._colorTextureRenderer = new TrianglesColorTextureRenderer(this._scene, false);
@@ -61080,6 +61167,34 @@ class Renderers {
61080
61167
  return this._colorTextureRendererWithSAO;
61081
61168
  }
61082
61169
 
61170
+ get colorTextureRendererAlphaCutoff() {
61171
+ if (!this._colorTextureRendererAlphaCutoff) {
61172
+ this._colorTextureRendererAlphaCutoff = new TrianglesColorTextureRenderer(this._scene, false, { useAlphaCutoff: true });
61173
+ }
61174
+ return this._colorTextureRendererAlphaCutoff;
61175
+ }
61176
+
61177
+ get colorTextureRendererWithSAOAlphaCutoff() {
61178
+ if (!this._colorTextureRendererWithSAOAlphaCutoff) {
61179
+ this._colorTextureRendererWithSAOAlphaCutoff = new TrianglesColorTextureRenderer(this._scene, true, { useAlphaCutoff: true });
61180
+ }
61181
+ return this._colorTextureRendererWithSAOAlphaCutoff;
61182
+ }
61183
+
61184
+ get pbrRenderer() {
61185
+ if (!this._pbrRenderer) {
61186
+ this._pbrRenderer = new TrianglesPBRRenderer(this._scene, false);
61187
+ }
61188
+ return this._pbrRenderer;
61189
+ }
61190
+
61191
+ get pbrRendererWithSAO() {
61192
+ if (!this._pbrRendererWithSAO) {
61193
+ this._pbrRendererWithSAO = new TrianglesPBRRenderer(this._scene, true);
61194
+ }
61195
+ return this._pbrRendererWithSAO;
61196
+ }
61197
+
61083
61198
  get silhouetteRenderer() {
61084
61199
  if (!this._silhouetteRenderer) {
61085
61200
  this._silhouetteRenderer = new TrianglesSilhouetteRenderer(this._scene);
@@ -61157,13 +61272,6 @@ class Renderers {
61157
61272
  return this._shadowRenderer;
61158
61273
  }
61159
61274
 
61160
- get snapInitRenderer() {
61161
- if (!this._snapInitRenderer) {
61162
- this._snapInitRenderer = new TrianglesSnapInitRenderer(this._scene, false);
61163
- }
61164
- return this._snapInitRenderer;
61165
- }
61166
-
61167
61275
  get snapRenderer() {
61168
61276
  if (!this._snapRenderer) {
61169
61277
  this._snapRenderer = new TrianglesSnapRenderer(this._scene);
@@ -61171,6 +61279,13 @@ class Renderers {
61171
61279
  return this._snapRenderer;
61172
61280
  }
61173
61281
 
61282
+ get snapInitRenderer() {
61283
+ if (!this._snapInitRenderer) {
61284
+ this._snapInitRenderer = new TrianglesSnapInitRenderer(this._scene);
61285
+ }
61286
+ return this._snapInitRenderer;
61287
+ }
61288
+
61174
61289
  _destroy() {
61175
61290
  if (this._colorRenderer) {
61176
61291
  this._colorRenderer.destroy();
@@ -61184,18 +61299,24 @@ class Renderers {
61184
61299
  if (this._flatColorRendererWithSAO) {
61185
61300
  this._flatColorRendererWithSAO.destroy();
61186
61301
  }
61187
- if (this._pbrRenderer) {
61188
- this._pbrRenderer.destroy();
61189
- }
61190
- if (this._pbrRendererWithSAO) {
61191
- this._pbrRendererWithSAO.destroy();
61192
- }
61193
61302
  if (this._colorTextureRenderer) {
61194
61303
  this._colorTextureRenderer.destroy();
61195
61304
  }
61196
61305
  if (this._colorTextureRendererWithSAO) {
61197
61306
  this._colorTextureRendererWithSAO.destroy();
61198
61307
  }
61308
+ if (this._colorTextureRendererAlphaCutoff) {
61309
+ this._colorTextureRendererAlphaCutoff.destroy();
61310
+ }
61311
+ if (this._colorTextureRendererWithSAOAlphaCutoff) {
61312
+ this._colorTextureRendererWithSAOAlphaCutoff.destroy();
61313
+ }
61314
+ if (this._pbrRenderer) {
61315
+ this._pbrRenderer.destroy();
61316
+ }
61317
+ if (this._pbrRendererWithSAO) {
61318
+ this._pbrRendererWithSAO.destroy();
61319
+ }
61199
61320
  if (this._depthRenderer) {
61200
61321
  this._depthRenderer.destroy();
61201
61322
  }
@@ -61245,22 +61366,22 @@ const cachedRenderers$5 = {};
61245
61366
  */
61246
61367
  function getRenderers$6(scene) {
61247
61368
  const sceneId = scene.id;
61248
- let instancingRenderers = cachedRenderers$5[sceneId];
61249
- if (!instancingRenderers) {
61250
- instancingRenderers = new Renderers(scene);
61251
- cachedRenderers$5[sceneId] = instancingRenderers;
61252
- instancingRenderers._compile();
61253
- instancingRenderers.eagerCreateRenders();
61369
+ let renderers = cachedRenderers$5[sceneId];
61370
+ if (!renderers) {
61371
+ renderers = new Renderers(scene);
61372
+ cachedRenderers$5[sceneId] = renderers;
61373
+ renderers._compile();
61374
+ renderers.eagerCreateRenders();
61254
61375
  scene.on("compile", () => {
61255
- instancingRenderers._compile();
61256
- instancingRenderers.eagerCreateRenders();
61376
+ renderers._compile();
61377
+ renderers.eagerCreateRenders();
61257
61378
  });
61258
61379
  scene.on("destroyed", () => {
61259
61380
  delete cachedRenderers$5[sceneId];
61260
- instancingRenderers._destroy();
61381
+ renderers._destroy();
61261
61382
  });
61262
61383
  }
61263
- return instancingRenderers;
61384
+ return renderers;
61264
61385
  }
61265
61386
 
61266
61387
  const tempUint8Vec4$2 = new Uint8Array(4);
@@ -62042,14 +62163,21 @@ class VBOInstancingTrianglesLayer {
62042
62163
  return;
62043
62164
  }
62044
62165
  this._updateBackfaceCull(renderFlags, frameCtx);
62166
+ const useAlphaCutoff = this._state.textureSet && (typeof(this._state.textureSet.alphaCutoff) === "number");
62045
62167
  if (frameCtx.withSAO && this.model.saoEnabled) {
62046
62168
  if (frameCtx.pbrEnabled && this.model.pbrEnabled && this._state.pbrSupported) {
62047
62169
  if (this._renderers.pbrRendererWithSAO) {
62048
62170
  this._renderers.pbrRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62049
62171
  }
62050
62172
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
62051
- if (this._renderers.colorTextureRendererWithSAO) {
62052
- this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62173
+ if (useAlphaCutoff) {
62174
+ if (this._renderers.colorTextureRendererWithSAOAlphaCutoff) {
62175
+ this._renderers.colorTextureRendererWithSAOAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62176
+ }
62177
+ } else {
62178
+ if (this._renderers.colorTextureRendererWithSAO) {
62179
+ this._renderers.colorTextureRendererWithSAO.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62180
+ }
62053
62181
  }
62054
62182
  } else if (this._state.normalsBuf) {
62055
62183
  if (this._renderers.colorRendererWithSAO) {
@@ -62065,8 +62193,14 @@ class VBOInstancingTrianglesLayer {
62065
62193
  this._renderers.pbrRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62066
62194
  }
62067
62195
  } else if (frameCtx.colorTextureEnabled && this.model.colorTextureEnabled && this._state.colorTextureSupported) {
62068
- if (this._renderers.colorTextureRenderer) {
62069
- this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62196
+ if (useAlphaCutoff) {
62197
+ if (this._renderers.colorTextureRendererAlphaCutoff) {
62198
+ this._renderers.colorTextureRendererAlphaCutoff.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62199
+ }
62200
+ } else {
62201
+ if (this._renderers.colorTextureRenderer) {
62202
+ this._renderers.colorTextureRenderer.drawLayer(frameCtx, this, RENDER_PASSES.COLOR_OPAQUE);
62203
+ }
62070
62204
  }
62071
62205
  } else if (this._state.normalsBuf) {
62072
62206
  if (this._renderers.colorRenderer) {
@@ -63241,7 +63375,7 @@ class VBOBatchingLinesSnapRenderer extends VBORenderer{
63241
63375
 
63242
63376
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
63243
63377
  src.push(`if (pickFlag != renderPass) {`);
63244
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
63378
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
63245
63379
  src.push(" } else {");
63246
63380
  src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); ");
63247
63381
  if (scene.entityOffsetsEnabled) {
@@ -64983,7 +65117,7 @@ class VBOInstancingLinesSnapRenderer extends VBORenderer {
64983
65117
  // renderPass = PICK
64984
65118
  src.push(`int pickFlag = int(flags) >> 12 & 0xF;`);
64985
65119
  src.push(`if (pickFlag != renderPass) {`);
64986
- src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex
65120
+ src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); // Cull vertex
64987
65121
  src.push("} else {");
64988
65122
  src.push(" vec4 worldPosition = positionsDecodeMatrix * vec4(position, 1.0); ");
64989
65123
  src.push(" worldPosition = worldMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0);");
@@ -75750,6 +75884,14 @@ class DTXTrianglesSnapRenderer {
75750
75884
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
75751
75885
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
75752
75886
 
75887
+ // flags.w = NOT_RENDERED | PICK
75888
+ // renderPass = PICK
75889
+
75890
+ src.push(`if (int(flags.w) != renderPass) {`);
75891
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
75892
+ src.push(" return;"); // Cull vertex
75893
+ src.push("}");
75894
+
75753
75895
  src.push("{");
75754
75896
 
75755
75897
  // get vertex base
@@ -76165,6 +76307,14 @@ class DTXTrianglesSnapInitRenderer {
76165
76307
  src.push("uvec4 flags = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+2, objectIndexCoords.y), 0);");
76166
76308
  src.push("uvec4 flags2 = texelFetch (uObjectPerObjectColorsAndFlags, ivec2(objectIndexCoords.x*8+3, objectIndexCoords.y), 0);");
76167
76309
 
76310
+ // flags.w = NOT_RENDERED | PICK
76311
+ // renderPass = PICK
76312
+
76313
+ src.push(`if (int(flags.w) != renderPass) {`);
76314
+ src.push(" gl_Position = vec4(3.0, 3.0, 3.0, 1.0);"); // Cull vertex
76315
+ src.push(" return;"); // Cull vertex
76316
+ src.push("}");
76317
+
76168
76318
  src.push("{");
76169
76319
 
76170
76320
  // get color
@@ -80557,6 +80707,11 @@ class SceneModelTextureSet {
80557
80707
  */
80558
80708
  this.colorTexture = cfg.colorTexture;
80559
80709
 
80710
+ /**
80711
+ * The alpha cutoff [float]
80712
+ */
80713
+ this.alphaCutoff = cfg.alphaCutoff;
80714
+
80560
80715
  /**
80561
80716
  * The metallic-roughness texture.
80562
80717
  * @type {SceneModelTexture|*}
@@ -85113,6 +85268,7 @@ class SceneModel extends Component {
85113
85268
  id: textureSetId,
85114
85269
  model: this,
85115
85270
  colorTexture,
85271
+ alphaCutoff: cfg.alphaCutoff,
85116
85272
  metallicRoughnessTexture,
85117
85273
  normalsTexture,
85118
85274
  emissiveTexture,
@@ -85546,6 +85702,14 @@ class SceneModel extends Component {
85546
85702
  return this._createMesh(cfg);
85547
85703
  }
85548
85704
 
85705
+ _createDefaultIndices(numIndices) {
85706
+ const indices = [];
85707
+ for (let i = 0; i < numIndices; i++) {
85708
+ indices.push(i);
85709
+ }
85710
+ return indices;
85711
+ }
85712
+
85549
85713
  _createMesh(cfg) {
85550
85714
  const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);
85551
85715
  mesh.pickId = this.scene._renderer.getPickID(mesh);
@@ -101595,8 +101759,6 @@ class MetaScene {
101595
101759
  * @param {String} modelId ID for the new {@link MetaModel}, which will have {@link MetaModel#id} set to this value.
101596
101760
  * @param {Object} metaModelData Data for the {@link MetaModel}.
101597
101761
  * @param {Object} [options] Options for creating the {@link MetaModel}.
101598
- * @param {Object} [options.includeTypes] When provided, only create {@link MetaObject}s with types in this list.
101599
- * @param {Object} [options.excludeTypes] When provided, never create {@link MetaObject}s with types in this list.
101600
101762
  * @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.
101601
101763
  * @returns {MetaModel} The new MetaModel.
101602
101764
  */
@@ -117582,40 +117744,6 @@ class GLTFSceneModelLoader {
117582
117744
  }
117583
117745
  }
117584
117746
 
117585
- function getMetaModelCorrections(metaModelJSON) {
117586
- const eachRootStats = {};
117587
- const eachChildRoot = {};
117588
- const metaObjects = metaModelJSON.metaObjects || [];
117589
- const metaObjectsMap = {};
117590
- for (let i = 0, len = metaObjects.length; i < len; i++) {
117591
- const metaObject = metaObjects[i];
117592
- metaObjectsMap[metaObject.id] = metaObject;
117593
- }
117594
- for (let i = 0, len = metaObjects.length; i < len; i++) {
117595
- const metaObject = metaObjects[i];
117596
- if (metaObject.parent !== undefined && metaObject.parent !== null) {
117597
- const metaObjectParent = metaObjectsMap[metaObject.parent];
117598
- if (metaObject.type === metaObjectParent.type) {
117599
- let rootMetaObject = metaObjectParent;
117600
- while (rootMetaObject.parent && metaObjectsMap[rootMetaObject.parent].type === rootMetaObject.type) {
117601
- rootMetaObject = metaObjectsMap[rootMetaObject.parent];
117602
- }
117603
- const rootStats = eachRootStats[rootMetaObject.id] || (eachRootStats[rootMetaObject.id] = {
117604
- numChildren: 0,
117605
- countChildren: 0
117606
- });
117607
- rootStats.numChildren++;
117608
- eachChildRoot[metaObject.id] = rootMetaObject;
117609
- }
117610
- }
117611
- }
117612
- return {
117613
- metaObjectsMap,
117614
- eachRootStats,
117615
- eachChildRoot
117616
- };
117617
- }
117618
-
117619
117747
  function loadGLTF(plugin, src, metaModelJSON, options, sceneModel, ok, error) {
117620
117748
  const spinner = plugin.viewer.scene.canvas.spinner;
117621
117749
  spinner.processes++;
@@ -117657,7 +117785,9 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
117657
117785
  const ctx = {
117658
117786
  src: src,
117659
117787
  entityId: options.entityId,
117660
- metaModelCorrections: metaModelJSON ? getMetaModelCorrections(metaModelJSON) : null,
117788
+ metaModelJSON,
117789
+ autoMetaModel: options.autoMetaModel,
117790
+ metaObjects: [],
117661
117791
  loadBuffer: options.loadBuffer,
117662
117792
  basePath: options.basePath,
117663
117793
  handlenode: options.handlenode,
@@ -117676,8 +117806,20 @@ function parseGLTF(plugin, src, gltf, metaModelJSON, options, sceneModel, ok) {
117676
117806
  };
117677
117807
  loadTextures(ctx);
117678
117808
  loadMaterials(ctx);
117809
+ if (options.autoMetaModel) {
117810
+ ctx.metaObjects.push({
117811
+ id: sceneModel.id,
117812
+ type: "Default",
117813
+ name: sceneModel.id
117814
+ });
117815
+ }
117679
117816
  loadDefaultScene(ctx);
117680
117817
  sceneModel.finalize();
117818
+ if (options.autoMetaModel) {
117819
+ plugin.viewer.metaScene.createMetaModel(sceneModel.id, {
117820
+ metaObjects: ctx.metaObjects
117821
+ });
117822
+ }
117681
117823
  spinner.processes--;
117682
117824
  ok();
117683
117825
  });
@@ -117806,23 +117948,17 @@ function loadTextureSet(ctx, material) {
117806
117948
  if (material.emissiveTexture) {
117807
117949
  textureSetCfg.emissiveTextureId = material.emissiveTexture.texture._textureId;
117808
117950
  }
117809
- // const alphaMode = material.alphaMode;
117810
- // switch (alphaMode) {
117811
- // case "NORMAL_OPAQUE":
117812
- // materialCfg.alphaMode = "opaque";
117813
- // break;
117814
- // case "MASK":
117815
- // materialCfg.alphaMode = "mask";
117816
- // break;
117817
- // case "BLEND":
117818
- // materialCfg.alphaMode = "blend";
117819
- // break;
117820
- // default:
117821
- // }
117822
- // const alphaCutoff = material.alphaCutoff;
117823
- // if (alphaCutoff !== undefined) {
117824
- // materialCfg.alphaCutoff = alphaCutoff;
117825
- // }
117951
+
117952
+ switch (material.alphaMode) {
117953
+ case "OPAQUE":
117954
+ break;
117955
+ case "MASK":
117956
+ const alphaCutoff = material.alphaCutoff;
117957
+ // Default from the spec https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#reference-material
117958
+ textureSetCfg.alphaCutoff = (alphaCutoff !== undefined) ? alphaCutoff : 0.5;
117959
+ break;
117960
+ }
117961
+
117826
117962
  const metallicPBR = material.pbrMetallicRoughness;
117827
117963
  if (material.pbrMetallicRoughness) {
117828
117964
  const pbrMetallicRoughness = material.pbrMetallicRoughness;
@@ -117868,7 +118004,7 @@ function loadMaterialAttributes(ctx, material) { // Substitute RGBA for material
117868
118004
  opacity: 1,
117869
118005
  metallic: 0,
117870
118006
  roughness: 1,
117871
- doubleSided : true
118007
+ doubleSided: true
117872
118008
  };
117873
118009
  if (extensions) {
117874
118010
  const specularPBR = extensions["KHR_materials_pbrSpecularGlossiness"];
@@ -117942,9 +118078,22 @@ function loadScene(ctx, scene) {
117942
118078
  const node = nodes[i];
117943
118079
  countMeshUsage(ctx, node);
117944
118080
  }
117945
- for (let i = 0, len = nodes.length; i < len; i++) {
118081
+ for (let i = 0, len = nodes.length; i < len && !ctx.nodesHaveNames; i++) {
117946
118082
  const node = nodes[i];
117947
- loadNode(ctx, node, 0, null);
118083
+ if (testIfNodesHaveNames(node)) {
118084
+ ctx.nodesHaveNames = true;
118085
+ }
118086
+ }
118087
+ if (!ctx.nodesHaveNames) {
118088
+ for (let i = 0, len = nodes.length; i < len; i++) {
118089
+ const node = nodes[i];
118090
+ parseNodesWithoutNames(ctx, node, 0, null);
118091
+ }
118092
+ } else {
118093
+ for (let i = 0, len = nodes.length; i < len; i++) {
118094
+ const node = nodes[i];
118095
+ parseNodesWithNames(ctx, node, 0, null);
118096
+ }
117948
118097
  }
117949
118098
  }
117950
118099
 
@@ -117966,10 +118115,131 @@ function countMeshUsage(ctx, node) {
117966
118115
  }
117967
118116
  }
117968
118117
 
117969
- const deferredMeshIds = [];
118118
+ function testIfNodesHaveNames(node) {
118119
+ if (node.name) {
118120
+ return true;
118121
+ }
118122
+ if (node.children) {
118123
+ const children = node.children;
118124
+ for (let i = 0, len = children.length; i < len; i++) {
118125
+ const childNode = children[i];
118126
+ if (testIfNodesHaveNames(childNode)) {
118127
+ return true;
118128
+ }
118129
+ }
118130
+ }
118131
+ return false;
118132
+ }
117970
118133
 
117971
- function loadNode(ctx, node, depth, matrix) {
117972
- ctx.gltfData;
118134
+ /**
118135
+ * Parses a glTF node hierarchy that is known to NOT contain "name" attributes on the nodes.
118136
+ * Create a SceneMesh for each mesh primitive, and a single SceneObject.
118137
+ */
118138
+ const parseNodesWithoutNames = (function () {
118139
+ const meshIds = [];
118140
+ return function (ctx, node, depth, matrix, parentNode) {
118141
+ matrix = parseNodeMatrix(node, matrix);
118142
+ if (node.mesh) {
118143
+ parseNodeMesh(node, ctx, matrix, meshIds);
118144
+ }
118145
+ if (node.children) {
118146
+ const children = node.children;
118147
+ for (let i = 0, len = children.length; i < len; i++) {
118148
+ const childNode = children[i];
118149
+ parseNodesWithoutNames(ctx, childNode, depth + 1, matrix, node);
118150
+ }
118151
+ }
118152
+ if (depth === 0) {
118153
+ let entityId = "entity-" + ctx.nextId++;
118154
+ if (meshIds && meshIds.length > 0) {
118155
+ ctx.sceneModel.createEntity({
118156
+ id: entityId,
118157
+ meshIds,
118158
+ isObject: true
118159
+ });
118160
+ if (ctx.autoMetaModel) {
118161
+ ctx.metaObjects.push({
118162
+ id: entityId,
118163
+ type: "Default",
118164
+ name: entityId,
118165
+ parent: ctx.sceneModel.id
118166
+ });
118167
+ }
118168
+ meshIds.length = 0;
118169
+ }
118170
+ }
118171
+ }
118172
+ })();
118173
+
118174
+ const parseNodesWithNames = (function () {
118175
+
118176
+ const objectIdStack = [];
118177
+ const meshIdsStack = [];
118178
+ let meshIds = [];
118179
+
118180
+ return function (ctx, node, depth, matrix) {
118181
+ matrix = parseNodeMatrix(node, matrix);
118182
+ if (meshIds && node.mesh) {
118183
+ parseNodeMesh(node, ctx, matrix, meshIds);
118184
+ }
118185
+
118186
+ if (node.name) {
118187
+ meshIds = [];
118188
+ let entityId = node.name;
118189
+ if (!!entityId && ctx.sceneModel.objects[entityId]) ;
118190
+ while (!entityId || ctx.sceneModel.objects[entityId]) {
118191
+ entityId = "entity-" + ctx.nextId++;
118192
+ }
118193
+ objectIdStack.push(entityId);
118194
+ meshIdsStack.push(meshIds);
118195
+ }
118196
+
118197
+ if (node.children) {
118198
+ const children = node.children;
118199
+ for (let i = 0, len = children.length; i < len; i++) {
118200
+ const childNode = children[i];
118201
+ parseNodesWithNames(ctx, childNode, depth + 1, matrix);
118202
+ }
118203
+ }
118204
+
118205
+ // Post-order visit scene node
118206
+
118207
+ const nodeName = node.name;
118208
+ if ((nodeName !== undefined && nodeName !== null) || depth === 0) {
118209
+ let entityId = objectIdStack.pop();
118210
+ if (!entityId) { // For when there are no nodes with names
118211
+ entityId = "entity-" + ctx.nextId++;
118212
+ }
118213
+ let entityMeshIds = meshIdsStack.pop();
118214
+ if (meshIds && meshIds.length > 0) {
118215
+ ctx.sceneModel.createEntity({
118216
+ id: entityId,
118217
+ meshIds: entityMeshIds,
118218
+ isObject: true
118219
+ });
118220
+ if (ctx.autoMetaModel) {
118221
+ ctx.metaObjects.push({
118222
+ id: entityId,
118223
+ type: "Default",
118224
+ name: entityId,
118225
+ parent: ctx.sceneModel.id
118226
+ });
118227
+ }
118228
+ }
118229
+ meshIds = meshIdsStack.length > 0 ? meshIdsStack[meshIdsStack.length - 1] : null;
118230
+ }
118231
+ };
118232
+ })();
118233
+
118234
+
118235
+ /**
118236
+ * Parses transform at the given glTF node.
118237
+ *
118238
+ * @param node the glTF node
118239
+ * @param matrix Transfor matrix from parent nodes
118240
+ * @returns {*} Transform matrix for the node
118241
+ */
118242
+ function parseNodeMatrix(node, matrix) {
117973
118243
  let localMatrix;
117974
118244
  if (node.matrix) {
117975
118245
  localMatrix = node.matrix;
@@ -118003,171 +118273,96 @@ function loadNode(ctx, node, depth, matrix) {
118003
118273
  matrix = localMatrix;
118004
118274
  }
118005
118275
  }
118276
+ return matrix;
118277
+ }
118006
118278
 
118007
- const sceneModel = ctx.sceneModel;
118008
- if (node.mesh) {
118009
- const mesh = node.mesh;
118010
- if (ctx.handlenode) {
118011
- const actions = {};
118012
- if (!ctx.handlenode(ctx.sceneModel.id, node, actions)) {
118013
- return;
118014
- }
118015
- if (actions.createEntity) ;
118016
- }
118017
- const worldMatrix = matrix ? matrix.slice() : math.identityMat4();
118018
- const numPrimitives = mesh.primitives.length;
118019
-
118020
- if (numPrimitives > 0) {
118021
-
118022
- for (let i = 0; i < numPrimitives; i++) {
118023
-
118024
- const primitive = mesh.primitives[i];
118025
- if (primitive.mode < 4) {
118026
- continue;
118027
- }
118028
-
118029
- const meshCfg = {
118030
- id: sceneModel.id + "." + ctx.numObjects++
118031
- };
118032
-
118033
- const material = primitive.material;
118034
- if (material) {
118035
- meshCfg.textureSetId = material._textureSetId;
118036
- meshCfg.color = material._attributes.color;
118037
- meshCfg.opacity = material._attributes.opacity;
118038
- meshCfg.metallic = material._attributes.metallic;
118039
- meshCfg.roughness = material._attributes.roughness;
118040
- } else {
118041
- meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);
118042
- meshCfg.opacity = 1.0;
118043
- }
118044
-
118045
- const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));
118046
-
118047
- switch (primitive.mode) {
118048
- case 0: // POINTS
118049
- meshCfg.primitive = "points";
118050
- break;
118051
- case 1: // LINES
118052
- meshCfg.primitive = "lines";
118053
- break;
118054
- case 2: // LINE_LOOP
118055
- meshCfg.primitive = "lines";
118056
- break;
118057
- case 3: // LINE_STRIP
118058
- meshCfg.primitive = "lines";
118059
- break;
118060
- case 4: // TRIANGLES
118061
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118062
- break;
118063
- case 5: // TRIANGLE_STRIP
118064
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118065
- break;
118066
- case 6: // TRIANGLE_FAN
118067
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118068
- break;
118069
- default:
118070
- meshCfg.primitive = backfaces ? "triangles" : "solid";
118071
- }
118072
-
118073
- const POSITION = primitive.attributes.POSITION;
118074
- if (!POSITION) {
118075
- continue;
118076
- }
118077
- meshCfg.localPositions = POSITION.value;
118078
- meshCfg.positions = new Float64Array(meshCfg.localPositions.length);
118079
-
118080
- if (primitive.attributes.NORMAL) {
118081
- meshCfg.normals = primitive.attributes.NORMAL.value;
118082
- }
118083
-
118084
- if (primitive.attributes.TEXCOORD_0) {
118085
- meshCfg.uv = primitive.attributes.TEXCOORD_0.value;
118086
- }
118087
-
118088
- if (primitive.indices) {
118089
- meshCfg.indices = primitive.indices.value;
118090
- }
118091
-
118092
- math.transformPositions3(worldMatrix, meshCfg.localPositions, meshCfg.positions);
118093
- const origin = math.vec3();
118094
- const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
118095
- if (rtcNeeded) {
118096
- meshCfg.origin = origin;
118097
- }
118098
-
118099
- sceneModel.createMesh(meshCfg);
118100
- deferredMeshIds.push(meshCfg.id);
118101
- }
118102
- }
118103
- }
118104
-
118105
- if (node.children) {
118106
- const children = node.children;
118107
- for (let i = 0, len = children.length; i < len; i++) {
118108
- const childNode = children[i];
118109
- loadNode(ctx, childNode, depth + 1, matrix);
118110
- }
118279
+ /**
118280
+ * Parses primitives referenced by the mesh belonging to the given node, creating XKTMeshes in the XKTModel.
118281
+ *
118282
+ * @param node glTF node
118283
+ * @param ctx Parsing context
118284
+ * @param matrix Matrix for the XKTMeshes
118285
+ * @param meshIds returns IDs of the new XKTMeshes
118286
+ */
118287
+ function parseNodeMesh(node, ctx, matrix, meshIds) {
118288
+ const mesh = node.mesh;
118289
+ if (!mesh) {
118290
+ return;
118111
118291
  }
118112
-
118113
- // Post-order visit scene node
118114
-
118115
- if (ctx.entityId) {
118116
- if (depth ===0) {
118117
- sceneModel.createEntity({
118118
- id: ctx.entityId,
118119
- meshIds: deferredMeshIds,
118120
- isObject: true
118121
- });
118122
- deferredMeshIds.length = 0;
118123
- }
118124
- } else {
118125
- const nodeName = node.name;
118126
- if (((nodeName !== undefined && nodeName !== null) || depth === 0) && deferredMeshIds.length > 0) {
118127
- if (nodeName === undefined || nodeName === null) {
118128
- ctx.log(`Warning: 'name' properties not found on glTF scene nodes - will randomly-generate object IDs in XKT`);
118292
+ const numPrimitives = mesh.primitives.length;
118293
+ if (numPrimitives > 0) {
118294
+ for (let i = 0; i < numPrimitives; i++) {
118295
+ const primitive = mesh.primitives[i];
118296
+ if (primitive.mode < 4) {
118297
+ continue;
118129
118298
  }
118130
- let entityId = nodeName; // Fall back on generated ID when `name` not found on glTF scene node(s)
118131
- // if (!!entityId && sceneModel.entities[entityId]) {
118132
- // ctx.log(`Warning: Two or more glTF nodes found with same 'name' attribute: '${nodeName} - will randomly-generating an object ID in XKT`);
118133
- // }
118134
- // while (!entityId || sceneModel.entities[entityId]) {
118135
- // entityId = "entity-" + ctx.nextId++;
118136
- // }
118137
- if (ctx.metaModelCorrections) {
118138
- // Merging meshes into XKTObjects that map to metaobjects
118139
- const rootMetaObject = ctx.metaModelCorrections.eachChildRoot[entityId];
118140
- if (rootMetaObject) {
118141
- const rootMetaObjectStats = ctx.metaModelCorrections.eachRootStats[rootMetaObject.id];
118142
- rootMetaObjectStats.countChildren++;
118143
- if (rootMetaObjectStats.countChildren >= rootMetaObjectStats.numChildren) {
118144
- sceneModel.createEntity({
118145
- id: rootMetaObject.id,
118146
- meshIds: deferredMeshIds,
118147
- isObject: true
118148
- });
118149
- deferredMeshIds.length = 0;
118150
- }
118151
- } else {
118152
- const metaObject = ctx.metaModelCorrections.metaObjectsMap[entityId];
118153
- if (metaObject) {
118154
- sceneModel.createEntity({
118155
- id: entityId,
118156
- meshIds: deferredMeshIds,
118157
- isObject: true
118158
- });
118159
- deferredMeshIds.length = 0;
118160
- }
118161
- }
118299
+ const meshCfg = {
118300
+ id: ctx.sceneModel.id + "." + ctx.numObjects++
118301
+ };
118302
+ const material = primitive.material;
118303
+ if (material) {
118304
+ meshCfg.textureSetId = material._textureSetId;
118305
+ meshCfg.color = material._attributes.color;
118306
+ meshCfg.opacity = material._attributes.opacity;
118307
+ meshCfg.metallic = material._attributes.metallic;
118308
+ meshCfg.roughness = material._attributes.roughness;
118162
118309
  } else {
118163
- // Create an XKTObject from the meshes at each named glTF node, don't care about metaobjects
118164
- sceneModel.createEntity({
118165
- id: entityId,
118166
- meshIds: deferredMeshIds,
118167
- isObject: true
118168
- });
118169
- deferredMeshIds.length = 0;
118310
+ meshCfg.color = new Float32Array([1.0, 1.0, 1.0]);
118311
+ meshCfg.opacity = 1.0;
118312
+ }
118313
+ const backfaces = ((ctx.backfaces !== false) || (material && material.doubleSided !== false));
118314
+ switch (primitive.mode) {
118315
+ case 0: // POINTS
118316
+ meshCfg.primitive = "points";
118317
+ break;
118318
+ case 1: // LINES
118319
+ meshCfg.primitive = "lines";
118320
+ break;
118321
+ case 2: // LINE_LOOP
118322
+ meshCfg.primitive = "lines";
118323
+ break;
118324
+ case 3: // LINE_STRIP
118325
+ meshCfg.primitive = "lines";
118326
+ break;
118327
+ case 4: // TRIANGLES
118328
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118329
+ break;
118330
+ case 5: // TRIANGLE_STRIP
118331
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118332
+ break;
118333
+ case 6: // TRIANGLE_FAN
118334
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118335
+ break;
118336
+ default:
118337
+ meshCfg.primitive = backfaces ? "triangles" : "solid";
118338
+ }
118339
+ const POSITION = primitive.attributes.POSITION;
118340
+ if (!POSITION) {
118341
+ continue;
118342
+ }
118343
+ meshCfg.localPositions = POSITION.value;
118344
+ meshCfg.positions = new Float64Array(meshCfg.localPositions.length);
118345
+ if (primitive.attributes.NORMAL) {
118346
+ meshCfg.normals = primitive.attributes.NORMAL.value;
118347
+ }
118348
+ if (primitive.attributes.TEXCOORD_0) {
118349
+ meshCfg.uv = primitive.attributes.TEXCOORD_0.value;
118170
118350
  }
118351
+ if (primitive.indices) {
118352
+ meshCfg.indices = primitive.indices.value;
118353
+ }
118354
+ if (matrix) {
118355
+ math.transformPositions3(matrix, meshCfg.localPositions, meshCfg.positions);
118356
+ } else { // eqiv to math.transformPositions3(math.identityMat4(), meshCfg.localPositions, meshCfg.positions);
118357
+ meshCfg.positions.set(meshCfg.localPositions);
118358
+ }
118359
+ const origin = math.vec3();
118360
+ const rtcNeeded = worldToRTCPositions(meshCfg.positions, meshCfg.positions, origin); // Small cellsize guarantees better accuracy
118361
+ if (rtcNeeded) {
118362
+ meshCfg.origin = origin;
118363
+ }
118364
+ ctx.sceneModel.createMesh(meshCfg);
118365
+ meshIds.push(meshCfg.id);
118171
118366
  }
118172
118367
  }
118173
118368
  }
@@ -118494,8 +118689,6 @@ class GLTFLoaderPlugin extends Plugin {
118494
118689
  * @param {String} [params.metaModelSrc] Path to an optional metadata file, as an alternative to the ````metaModelJSON```` parameter.
118495
118690
  * @param {*} [params.metaModelJSON] JSON model metadata, as an alternative to the ````metaModelSrc```` parameter.
118496
118691
  * @param {{String:Object}} [params.objectDefaults] Map of initial default states for each loaded {@link Entity} that represents an object. Default value is {@link IFCObjectDefaults}.
118497
- * @param {String[]} [params.includeTypes] When loading metadata, only loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
118498
- * @param {String[]} [params.excludeTypes] When loading metadata, never loads objects that have {@link MetaObject}s with {@link MetaObject#type} values in this list.
118499
118692
  * @param {Boolean} [params.edges=false] Whether or not xeokit renders the model with edges emphasized.
118500
118693
  * @param {Number[]} [params.origin=[0,0,0]] The double-precision World-space origin of the model's coordinates.
118501
118694
  * @param {Number[]} [params.position=[0,0,0]] The single-precision position, relative to ````origin````.
@@ -118511,150 +118704,47 @@ class GLTFLoaderPlugin extends Plugin {
118511
118704
  * represent the returned model. Set false to always use vertex buffer objects (VBOs). Note that DTX is only applicable
118512
118705
  * to non-textured triangle meshes, and that VBOs are always used for meshes that have textures, line segments, or point
118513
118706
  * primitives. Only works while {@link DTX#enabled} is also ````true````.
118514
- * @param {String} [params.entityId] When supplied, causes the entire model to be loaded into a single {@link Entity} that gets this ID.
118707
+ * @param {Boolean} [params.autoMetaModel] When supplied, creates a default MetaModel with a single MetaObject.
118515
118708
  * @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}
118516
118709
  */
118517
118710
  load(params = {}) {
118518
-
118519
118711
  if (params.id && this.viewer.scene.components[params.id]) {
118520
118712
  this.error("Component with this ID already exists in viewer: " + params.id + " - will autogenerate this ID");
118521
118713
  delete params.id;
118522
118714
  }
118523
-
118524
118715
  const sceneModel = new SceneModel(this.viewer.scene, utils.apply(params, {
118525
118716
  isModel: true,
118526
118717
  dtxEnabled: params.dtxEnabled
118527
118718
  }));
118528
-
118529
118719
  const modelId = sceneModel.id; // In case ID was auto-generated
118530
-
118531
118720
  if (!params.src && !params.gltf) {
118532
118721
  this.error("load() param expected: src or gltf");
118533
118722
  return sceneModel; // Return new empty model
118534
118723
  }
118535
-
118536
118724
  if (params.metaModelSrc || params.metaModelJSON) {
118537
-
118538
- const objectDefaults = params.objectDefaults || this._objectDefaults || IFCObjectDefaults;
118539
-
118540
118725
  const processMetaModelJSON = (metaModelJSON) => {
118541
-
118542
- this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {
118543
- includeTypes: params.includeTypes,
118544
- excludeTypes: params.excludeTypes
118545
- });
118546
-
118726
+ this.viewer.metaScene.createMetaModel(modelId, metaModelJSON, {});
118547
118727
  this.viewer.scene.canvas.spinner.processes--;
118548
-
118549
- let includeTypes;
118550
- if (params.includeTypes) {
118551
- includeTypes = {};
118552
- for (let i = 0, len = params.includeTypes.length; i < len; i++) {
118553
- includeTypes[params.includeTypes[i]] = true;
118554
- }
118555
- }
118556
- if (params.excludeTypes) {
118557
- if (!includeTypes) {
118558
- includeTypes = {};
118559
- }
118560
- for (let i = 0, len = params.excludeTypes.length; i < len; i++) {
118561
- includeTypes[params.excludeTypes[i]] = true;
118562
- }
118563
- }
118564
-
118565
- params.readableGeometry = false;
118566
-
118567
- params.handleGLTFNode = (modelId, glTFNode, actions) => {
118568
-
118569
- const name = glTFNode.name;
118570
-
118571
- if (!name) {
118572
- return true; // Continue descending this node subtree
118573
- }
118574
-
118575
- const nodeId = name;
118576
- const metaObject = this.viewer.metaScene.metaObjects[nodeId];
118577
- const type = (metaObject ? metaObject.type : "DEFAULT") || "DEFAULT";
118578
-
118579
- actions.createEntity = {
118580
- id: nodeId,
118581
- isObject: true // Registers the Entity in Scene#objects
118582
- };
118583
-
118584
- const props = objectDefaults[type];
118585
-
118586
- if (props) { // Set Entity's initial rendering state for recognized type
118587
-
118588
- if (props.visible === false) {
118589
- actions.createEntity.visible = false;
118590
- }
118591
-
118592
- if (props.colorize) {
118593
- actions.createEntity.colorize = props.colorize;
118594
- }
118595
-
118596
- if (props.pickable === false) {
118597
- actions.createEntity.pickable = false;
118598
- }
118599
-
118600
- if (props.opacity !== undefined && props.opacity !== null) {
118601
- actions.createEntity.opacity = props.opacity;
118602
- }
118603
- }
118604
-
118605
- return true; // Continue descending this glTF node subtree
118606
- };
118607
-
118608
118728
  if (params.src) {
118609
118729
  this._sceneModelLoader.load(this, params.src, metaModelJSON, params, sceneModel);
118610
118730
  } else {
118611
118731
  this._sceneModelLoader.parse(this, params.gltf, metaModelJSON, params, sceneModel);
118612
118732
  }
118613
118733
  };
118614
-
118615
118734
  if (params.metaModelSrc) {
118616
-
118617
118735
  const metaModelSrc = params.metaModelSrc;
118618
-
118619
118736
  this.viewer.scene.canvas.spinner.processes++;
118620
-
118621
118737
  this._dataSource.getMetaModel(metaModelSrc, (metaModelJSON) => {
118622
-
118623
118738
  this.viewer.scene.canvas.spinner.processes--;
118624
-
118625
118739
  processMetaModelJSON(metaModelJSON);
118626
-
118627
118740
  }, (errMsg) => {
118628
118741
  this.error(`load(): Failed to load model metadata for model '${modelId} from '${metaModelSrc}' - ${errMsg}`);
118629
118742
  this.viewer.scene.canvas.spinner.processes--;
118630
118743
  });
118631
-
118632
118744
  } else if (params.metaModelJSON) {
118633
-
118634
118745
  processMetaModelJSON(params.metaModelJSON);
118635
118746
  }
118636
-
118637
118747
  } else {
118638
-
118639
- params.handleGLTFNode = (modelId, glTFNode, actions) => {
118640
-
118641
- const name = glTFNode.name;
118642
-
118643
- if (!name) {
118644
- return true; // Continue descending this node subtree
118645
- }
118646
-
118647
- const id = name;
118648
-
118649
- actions.createEntity = { // Create an Entity for this glTF scene node
118650
- id: id,
118651
- isObject: true // Registers the Entity in Scene#objects
118652
- };
118653
-
118654
- return true; // Continue descending this glTF node subtree
118655
- };
118656
-
118657
-
118658
118748
  if (params.src) {
118659
118749
  this._sceneModelLoader.load(this, params.src, null, params, sceneModel);
118660
118750
  } else {
@@ -126990,7 +127080,7 @@ class TreeViewPlugin extends Plugin {
126990
127080
  this._nodeNodes[buildingNode.nodeId] = buildingNode;
126991
127081
  } else if (metaObjectType === "IfcBuildingStorey") {
126992
127082
  if (!buildingNode) {
126993
- 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");
127083
+ this.error("Failed to build storeys hierarchy for model - model does not have an IfcBuilding object, or is not an IFC model");
126994
127084
  return;
126995
127085
  }
126996
127086
  storeyNode = {
@@ -139177,49 +139267,126 @@ class DotBIMLoaderPlugin extends Plugin {
139177
139267
 
139178
139268
  const dbMeshId = element.mesh_id;
139179
139269
 
139180
- parseDBMesh(dbMeshId);
139181
-
139182
- const meshId = `${objectId}-mesh`;
139183
139270
  const vector = element.vector;
139184
139271
  const rotation = element.rotation;
139185
139272
  const props = objectDefaults ? objectDefaults[elementType] || objectDefaults["DEFAULT"] : null;
139186
-
139187
139273
  let visible = true;
139188
139274
  let pickable = true;
139189
- let color = element.color ? [element.color.r / 255, element.color.g / 255, element.color.b / 255] : [1, 1, 1];
139190
- let opacity = element.color ? element.color.a / 255 : 1.0;
139191
139275
 
139192
- if (props) {
139193
- if (props.visible === false) {
139194
- visible = false;
139195
- }
139196
- if (props.pickable === false) {
139197
- pickable = false;
139198
- }
139199
- if (props.colorize) {
139200
- color = props.colorize;
139201
- }
139202
- if (props.opacity !== undefined && props.opacity !== null) {
139203
- opacity = props.opacity;
139276
+ if (element.face_colors === undefined) {
139277
+
139278
+ parseDBMesh(dbMeshId);
139279
+
139280
+ const meshId = `${objectId}-mesh`;
139281
+
139282
+ let color = element.color ? [element.color.r / 255.0, element.color.g / 255.0, element.color.b / 255.0] : [1, 1, 1];
139283
+ let opacity = element.color ? element.color.a / 255.0 : 1.0;
139284
+
139285
+ if (props) {
139286
+ if (props.visible === false) {
139287
+ visible = false;
139288
+ }
139289
+ if (props.pickable === false) {
139290
+ pickable = false;
139291
+ }
139292
+ if (props.colorize) {
139293
+ color = props.colorize;
139294
+ }
139295
+ if (props.opacity !== undefined && props.opacity !== null) {
139296
+ opacity = props.opacity;
139297
+ }
139204
139298
  }
139299
+
139300
+ sceneModel.createMesh({
139301
+ id: meshId,
139302
+ geometryId: dbMeshId,
139303
+ color: color,
139304
+ opacity: opacity,
139305
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
139306
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
139307
+ });
139308
+
139309
+ sceneModel.createEntity({
139310
+ id: objectId,
139311
+ meshIds: [meshId],
139312
+ visible: visible,
139313
+ pickable: pickable,
139314
+ isObject: true
139315
+ });
139205
139316
  }
139317
+ else {
139318
+ let faceColors = element.face_colors;
139319
+ let coloredTrianglesDictionary = {};
139320
+ let currentTriangleIndicesCount = 0;
139321
+ let dbMesh = fileData.meshes[element.mesh_id];
139322
+ for (let i = 0, len = faceColors.length; i < len; i+=4) {
139323
+ let faceColor = [faceColors[i], faceColors[i+1], faceColors[i+2], faceColors[i+3]];
139324
+ if (coloredTrianglesDictionary[faceColor] === undefined) {
139325
+ coloredTrianglesDictionary[faceColor] = [];
139326
+ }
139327
+ let indexForPoint0 = dbMesh.indices[currentTriangleIndicesCount];
139328
+ let x0 = dbMesh.coordinates[indexForPoint0*3];
139329
+ let y0 = dbMesh.coordinates[indexForPoint0*3+1];
139330
+ let z0 = dbMesh.coordinates[indexForPoint0*3+2];
139331
+ let indexForPoint1 = dbMesh.indices[currentTriangleIndicesCount+1];
139332
+ let x1 = dbMesh.coordinates[indexForPoint1*3];
139333
+ let y1 = dbMesh.coordinates[indexForPoint1*3+1];
139334
+ let z1 = dbMesh.coordinates[indexForPoint1*3+2];
139335
+ let indexForPoint2 = dbMesh.indices[currentTriangleIndicesCount+2];
139336
+ let x2 = dbMesh.coordinates[indexForPoint2*3];
139337
+ let y2 = dbMesh.coordinates[indexForPoint2*3+1];
139338
+ let z2 = dbMesh.coordinates[indexForPoint2*3+2];
139339
+ coloredTrianglesDictionary[faceColor].push(x0, y0, z0, x1, y1, z1, x2, y2, z2);
139340
+
139341
+ currentTriangleIndicesCount += 3;
139342
+ }
139343
+ let meshIds = [];
139344
+ for (const [faceColor, trianglesCoordinates] of Object.entries(coloredTrianglesDictionary)) {
139345
+ sceneModel.createGeometry({
139346
+ id: `${dbMeshId}-${faceColor}`,
139347
+ primitive: "triangles",
139348
+ positions: trianglesCoordinates,
139349
+ indices: [...Array(trianglesCoordinates.length).keys()]
139350
+ });
139351
+ const meshId = `${objectId}-mesh-${faceColor}`;
139352
+ const faceColorArray = faceColor.split(',').map(Number);
139206
139353
 
139207
- sceneModel.createMesh({
139208
- id: meshId,
139209
- geometryId: dbMeshId,
139210
- color,
139211
- opacity,
139212
- quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
139213
- position: vector ? [vector.x, vector.y, vector.z] : undefined
139214
- });
139354
+ let color = [faceColorArray[0] / 255.0, faceColorArray[1] / 255.0, faceColorArray[2] / 255.0];
139355
+ let opacity = faceColorArray[3] / 255.0;
139215
139356
 
139216
- sceneModel.createEntity({
139217
- id: objectId,
139218
- meshIds: [meshId],
139219
- visible,
139220
- pickable,
139221
- isObject: true
139222
- });
139357
+ if (props) {
139358
+ if (props.visible === false) {
139359
+ visible = false;
139360
+ }
139361
+ if (props.pickable === false) {
139362
+ pickable = false;
139363
+ }
139364
+ if (props.colorize) {
139365
+ color = props.colorize;
139366
+ }
139367
+ if (props.opacity !== undefined && props.opacity !== null) {
139368
+ opacity = props.opacity;
139369
+ }
139370
+ }
139371
+
139372
+ sceneModel.createMesh({
139373
+ id: meshId,
139374
+ geometryId: `${dbMeshId}-${faceColor}`,
139375
+ color: color,
139376
+ opacity: opacity,
139377
+ quaternion: rotation && (rotation.qz !== 0 || rotation.qy !== 0 || rotation.qx !== 0 || rotation.qw !== 1.0) ? [rotation.qx, rotation.qy, rotation.qz, rotation.qw] : undefined,
139378
+ position: vector ? [vector.x, vector.y, vector.z] : undefined
139379
+ });
139380
+ meshIds.push(meshId);
139381
+ }
139382
+ sceneModel.createEntity({
139383
+ id: objectId,
139384
+ meshIds: meshIds,
139385
+ visible: visible,
139386
+ pickable: pickable,
139387
+ isObject: true
139388
+ });
139389
+ }
139223
139390
 
139224
139391
  for (let infoKey in info) {
139225
139392
  let properties;