@xeokit/xeokit-sdk 2.6.84 → 2.6.85-renderers-refactor-v2

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 (183) hide show
  1. package/dist/xeokit-sdk.cjs.js +13077 -44659
  2. package/dist/xeokit-sdk.es.js +13078 -44658
  3. package/dist/xeokit-sdk.es5.js +1402 -3502
  4. package/dist/xeokit-sdk.min.cjs.js +8 -8
  5. package/dist/xeokit-sdk.min.es.js +8 -8
  6. package/dist/xeokit-sdk.min.es5.js +7 -7
  7. package/package.json +1 -1
  8. package/src/plugins/lib/ui/index.js +12 -0
  9. package/src/viewer/Viewer.js +55 -103
  10. package/src/viewer/scene/canvas/Canvas.js +3 -43
  11. package/src/viewer/scene/geometry/ReadableGeometry.js +0 -25
  12. package/src/viewer/scene/lights/CubeTexture.js +0 -13
  13. package/src/viewer/scene/lights/DirLight.js +2 -1
  14. package/src/viewer/scene/lights/PointLight.js +2 -1
  15. package/src/viewer/scene/materials/Texture.js +0 -9
  16. package/src/viewer/scene/math/rtcCoords.js +1 -38
  17. package/src/viewer/scene/mesh/Mesh.js +454 -212
  18. package/src/viewer/scene/mesh/draw/DrawShaderSource.js +305 -1502
  19. package/src/viewer/scene/mesh/draw/LambertShaderSource.js +35 -0
  20. package/src/viewer/scene/mesh/emphasis/EmphasisShaderSource.js +34 -0
  21. package/src/viewer/scene/mesh/occlusion/OcclusionShaderSource.js +9 -157
  22. package/src/viewer/scene/mesh/pick/PickMeshShaderSource.js +21 -150
  23. package/src/viewer/scene/mesh/pick/PickTriangleShaderSource.js +12 -124
  24. package/src/viewer/scene/mesh/shadow/ShadowShaderSource.js +22 -97
  25. package/src/viewer/scene/model/SceneModel.js +245 -861
  26. package/src/viewer/scene/model/SceneModelEntity.js +4 -4
  27. package/src/viewer/scene/model/SceneModelMesh.js +3 -3
  28. package/src/viewer/scene/model/layer/DTXLayer.js +940 -0
  29. package/src/viewer/scene/model/layer/Layer.js +786 -0
  30. package/src/viewer/scene/model/layer/VBOLayer.js +1019 -0
  31. package/src/viewer/scene/model/layer/programs/ColorProgram.js +35 -0
  32. package/src/viewer/scene/model/layer/programs/ColorTextureProgram.js +46 -0
  33. package/src/viewer/scene/model/layer/programs/DepthProgram.js +11 -0
  34. package/src/viewer/scene/model/layer/programs/EdgesProgram.js +12 -0
  35. package/src/viewer/scene/model/layer/programs/FlatColorProgram.js +24 -0
  36. package/src/viewer/scene/model/layer/programs/OcclusionProgram.js +12 -0
  37. package/src/viewer/scene/model/layer/programs/PBRProgram.js +180 -0
  38. package/src/viewer/scene/model/layer/programs/PickDepthProgram.js +30 -0
  39. package/src/viewer/scene/model/layer/programs/PickMeshProgram.js +12 -0
  40. package/src/viewer/scene/model/layer/programs/PickNormalsProgram.js +18 -0
  41. package/src/viewer/scene/model/layer/programs/ShadowProgram.js +23 -0
  42. package/src/viewer/scene/model/layer/programs/SilhouetteProgram.js +15 -0
  43. package/src/viewer/scene/model/layer/programs/SnapProgram.js +28 -0
  44. package/src/viewer/scene/scene/Scene.js +21 -38
  45. package/src/viewer/scene/webgl/ArrayBuf.js +5 -20
  46. package/src/viewer/scene/webgl/FrameContext.js +14 -86
  47. package/src/viewer/scene/webgl/RenderBuffer.js +62 -262
  48. package/src/viewer/scene/webgl/Renderer.js +880 -843
  49. package/src/viewer/scene/webgl/WebGLRenderer.js +612 -0
  50. package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +60 -132
  51. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +167 -328
  52. package/src/viewer/scene/mesh/draw/DrawRenderer.js +0 -996
  53. package/src/viewer/scene/mesh/emphasis/EmphasisEdgesRenderer.js +0 -259
  54. package/src/viewer/scene/mesh/emphasis/EmphasisEdgesShaderSource.js +0 -159
  55. package/src/viewer/scene/mesh/emphasis/EmphasisFillRenderer.js +0 -286
  56. package/src/viewer/scene/mesh/emphasis/EmphasisFillShaderSource.js +0 -262
  57. package/src/viewer/scene/mesh/occlusion/OcclusionRenderer.js +0 -221
  58. package/src/viewer/scene/mesh/pick/PickMeshRenderer.js +0 -223
  59. package/src/viewer/scene/mesh/pick/PickTriangleRenderer.js +0 -200
  60. package/src/viewer/scene/mesh/shadow/ShadowRenderer.js +0 -214
  61. package/src/viewer/scene/model/RENDER_PASSES.js +0 -34
  62. package/src/viewer/scene/model/dtx/BindableDataTexture.js +0 -31
  63. package/src/viewer/scene/model/dtx/lines/DTXLinesBuffer.js +0 -27
  64. package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +0 -897
  65. package/src/viewer/scene/model/dtx/lines/DTXLinesState.js +0 -46
  66. package/src/viewer/scene/model/dtx/lines/DTXLinesTextureFactory.js +0 -411
  67. package/src/viewer/scene/model/dtx/lines/dataTextureRamStats.js +0 -49
  68. package/src/viewer/scene/model/dtx/lines/rebucketPositions.js +0 -208
  69. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesColorRenderer.js +0 -389
  70. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesRenderers.js +0 -65
  71. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +0 -1399
  72. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesBuffer.js +0 -46
  73. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesState.js +0 -250
  74. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesTextureFactory.js +0 -518
  75. package/src/viewer/scene/model/dtx/triangles/lib/dataTextureRamStats.js +0 -54
  76. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +0 -639
  77. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesDepthRenderer.js +0 -464
  78. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +0 -423
  79. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +0 -431
  80. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesNormalsRenderer.js +0 -345
  81. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesOcclusionRenderer.js +0 -436
  82. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickDepthRenderer.js +0 -466
  83. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickMeshRenderer.js +0 -437
  84. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsFlatRenderer.js +0 -460
  85. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsRenderer.js +0 -437
  86. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesRenderers.js +0 -307
  87. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +0 -472
  88. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +0 -474
  89. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +0 -435
  90. package/src/viewer/scene/model/vbo/ScratchMemory.js +0 -63
  91. package/src/viewer/scene/model/vbo/VBORenderer.js +0 -664
  92. package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +0 -704
  93. package/src/viewer/scene/model/vbo/batching/lines/lib/VBOBatchingLinesBuffer.js +0 -19
  94. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLineSnapInitRenderer.js +0 -318
  95. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesColorRenderer.js +0 -114
  96. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesRenderers.js +0 -99
  97. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSilhouetteRenderer.js +0 -124
  98. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapInitRenderer.js +0 -313
  99. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +0 -311
  100. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOSceneModelLineBatchingRenderer.js +0 -24
  101. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +0 -688
  102. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsRenderer.js +0 -24
  103. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsColorRenderer.js +0 -168
  104. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsOcclusionRenderer.js +0 -136
  105. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickDepthRenderer.js +0 -156
  106. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickMeshRenderer.js +0 -148
  107. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsRenderers.js +0 -144
  108. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsShadowRenderer.js +0 -107
  109. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSilhouetteRenderer.js +0 -146
  110. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapInitRenderer.js +0 -315
  111. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapRenderer.js +0 -305
  112. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesBuffer.js +0 -24
  113. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +0 -1346
  114. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesColorRenderer.js +0 -131
  115. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesEmphasisRenderer.js +0 -135
  116. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesRenderer.js +0 -12
  117. package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +0 -403
  118. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +0 -35
  119. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +0 -252
  120. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +0 -294
  121. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesDepthRenderer.js +0 -115
  122. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesFlatColorRenderer.js +0 -246
  123. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesNormalsRenderer.js +0 -139
  124. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesOcclusionRenderer.js +0 -125
  125. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPBRRenderer.js +0 -561
  126. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickDepthRenderer.js +0 -144
  127. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickMeshRenderer.js +0 -130
  128. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -121
  129. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -131
  130. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesShadowRenderer.js +0 -107
  131. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -144
  132. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapInitRenderer.js +0 -313
  133. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +0 -312
  134. package/src/viewer/scene/model/vbo/float16.js +0 -760
  135. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +0 -711
  136. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesColorRenderer.js +0 -148
  137. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderer.js +0 -26
  138. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderers.js +0 -139
  139. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSilhouetteRenderer.js +0 -127
  140. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapInitRenderer.js +0 -308
  141. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +0 -299
  142. package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +0 -733
  143. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsColorRenderer.js +0 -174
  144. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsDepthRenderer.js +0 -156
  145. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsOcclusionRenderer.js +0 -149
  146. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickDepthRenderer.js +0 -170
  147. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickMeshRenderer.js +0 -152
  148. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderer.js +0 -26
  149. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderers.js +0 -174
  150. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsShadowRenderer.js +0 -119
  151. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSilhouetteRenderer.js +0 -154
  152. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapInitRenderer.js +0 -307
  153. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapRenderer.js +0 -293
  154. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingTrianglesRenderer.js +0 -150
  155. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +0 -1289
  156. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesColorRenderer.js +0 -135
  157. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesEmphasisRenderer.js +0 -137
  158. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesRenderer.js +0 -12
  159. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +0 -403
  160. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +0 -267
  161. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +0 -299
  162. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesDepthRenderer.js +0 -126
  163. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatColorRenderer.js +0 -255
  164. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatNormalsRenderer.js +0 -130
  165. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +0 -32
  166. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesNormalsRenderer.js +0 -138
  167. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesOcclusionRenderer.js +0 -128
  168. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPBRRenderer.js +0 -561
  169. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickDepthRenderer.js +0 -149
  170. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickMeshRenderer.js +0 -136
  171. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -130
  172. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -145
  173. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesShadowRenderer.js +0 -113
  174. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -148
  175. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapInitRenderer.js +0 -319
  176. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +0 -310
  177. package/src/viewer/scene/webgl/Attribute.js +0 -23
  178. package/src/viewer/scene/webgl/Program.js +0 -181
  179. package/src/viewer/scene/webgl/RenderBufferManager.js +0 -34
  180. package/src/viewer/scene/webgl/Sampler.js +0 -18
  181. package/src/viewer/scene/webgl/Shader.js +0 -49
  182. package/src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js +0 -324
  183. package/src/viewer/scene/webgl/sao/SAOOcclusionRenderer.js +0 -384
@@ -2,15 +2,8 @@ import {Component} from "../Component.js";
2
2
  import {math} from "../math/math.js";
3
3
  import {buildEdgeIndices} from '../math/buildEdgeIndices.js';
4
4
  import {SceneModelMesh} from './SceneModelMesh.js';
5
- import {getScratchMemory, putScratchMemory} from "./vbo/ScratchMemory.js";
6
- import {VBOBatchingTrianglesLayer} from './vbo/batching/triangles/VBOBatchingTrianglesLayer.js';
7
- import {VBOInstancingTrianglesLayer} from './vbo/instancing/triangles/VBOInstancingTrianglesLayer.js';
8
- import {VBOBatchingLinesLayer} from './vbo/batching/lines/VBOBatchingLinesLayer.js';
9
- import {VBOInstancingLinesLayer} from './vbo/instancing/lines/VBOInstancingLinesLayer.js';
10
- import {VBOBatchingPointsLayer} from './vbo/batching/points/VBOBatchingPointsLayer.js';
11
- import {VBOInstancingPointsLayer} from './vbo/instancing/points/VBOInstancingPointsLayer.js';
12
- import {DTXLinesLayer} from "./dtx/lines/DTXLinesLayer.js";
13
- import {DTXTrianglesLayer} from "./dtx/triangles/DTXTrianglesLayer.js";
5
+ import {DTXLayer} from './layer/DTXLayer.js';
6
+ import {VBOLayer} from './layer/VBOLayer.js';
14
7
  import {ENTITY_FLAGS} from './ENTITY_FLAGS.js';
15
8
  import {RenderFlags} from "../webgl/RenderFlags.js";
16
9
  import {worldToRTCPositions} from "../math/rtcCoords.js";
@@ -1138,18 +1131,16 @@ export class SceneModel extends Component {
1138
1131
  this._enableVertexWelding = false; // Not needed for most objects, and very expensive, so disabled
1139
1132
  this._enableIndexBucketing = false; // Until fixed: https://github.com/xeokit/xeokit-sdk/issues/1204
1140
1133
 
1141
- this._vboBatchingLayerScratchMemory = getScratchMemory();
1142
1134
  this._textureTranscoder = cfg.textureTranscoder || getKTX2TextureTranscoder(this.scene.viewer);
1143
1135
 
1144
- this._maxGeometryBatchSize = cfg.maxGeometryBatchSize;
1136
+ this._maxGeometryBatchSize = cfg.maxGeometryBatchSize ?? 5000000;
1145
1137
 
1146
1138
  this._aabb = math.collapseAABB3();
1147
1139
  this._aabbDirty = true;
1148
1140
 
1149
1141
  this._quantizationRanges = {};
1150
1142
 
1151
- this._vboInstancingLayers = {};
1152
- this._vboBatchingLayers = {};
1143
+ this._vboLayers = {};
1153
1144
  this._dtxLayers = {};
1154
1145
 
1155
1146
  this._meshList = [];
@@ -1294,7 +1285,26 @@ export class SceneModel extends Component {
1294
1285
  }
1295
1286
  });
1296
1287
 
1297
- this._createDefaultTextureSet();
1288
+ // Every SceneModelMesh gets at least the default TextureSet,
1289
+ // which contains empty default textures filled with color
1290
+ const defineTex = (texId, preloadColor) => {
1291
+ return this._textures[texId] = new SceneModelTexture({
1292
+ id: texId,
1293
+ texture: new Texture2D({
1294
+ gl: this.scene.canvas.gl,
1295
+ preloadColor: preloadColor
1296
+ })
1297
+ });
1298
+ };
1299
+
1300
+ this._textureSets[DEFAULT_TEXTURE_SET_ID] = new SceneModelTextureSet({
1301
+ id: DEFAULT_TEXTURE_SET_ID,
1302
+ colorTexture: defineTex(DEFAULT_COLOR_TEXTURE_ID, [1, 1, 1, 1]), // [r, g, b, a]}),
1303
+ metallicRoughnessTexture: defineTex(DEFAULT_METAL_ROUGH_TEXTURE_ID, [0, 1, 1, 1]), // [_, roughness, metalness, _],
1304
+ normalsTexture: defineTex(DEFAULT_NORMALS_TEXTURE_ID, [0, 0, 0, 0]), // [x, y, z, _] - these must be zeros
1305
+ emissiveTexture: defineTex(DEFAULT_EMISSIVE_TEXTURE_ID, [0, 0, 0, 1]), // [x, y, z, _]
1306
+ occlusionTexture: defineTex(DEFAULT_OCCLUSION_TEXTURE_ID, [1, 1, 1, 1]) // [x, y, z, _]
1307
+ });
1298
1308
 
1299
1309
  this.visible = cfg.visible;
1300
1310
  this.culled = cfg.culled;
@@ -1316,60 +1326,6 @@ export class SceneModel extends Component {
1316
1326
  this._meshesWithDirtyMatrices[this._numMeshesWithDirtyMatrices++] = mesh;
1317
1327
  }
1318
1328
 
1319
- _createDefaultTextureSet() {
1320
- // Every SceneModelMesh gets at least the default TextureSet,
1321
- // which contains empty default textures filled with color
1322
- const defaultColorTexture = new SceneModelTexture({
1323
- id: DEFAULT_COLOR_TEXTURE_ID,
1324
- texture: new Texture2D({
1325
- gl: this.scene.canvas.gl,
1326
- preloadColor: [1, 1, 1, 1] // [r, g, b, a]})
1327
- })
1328
- });
1329
- const defaultMetalRoughTexture = new SceneModelTexture({
1330
- id: DEFAULT_METAL_ROUGH_TEXTURE_ID,
1331
- texture: new Texture2D({
1332
- gl: this.scene.canvas.gl,
1333
- preloadColor: [0, 1, 1, 1] // [unused, roughness, metalness, unused]
1334
- })
1335
- });
1336
- const defaultNormalsTexture = new SceneModelTexture({
1337
- id: DEFAULT_NORMALS_TEXTURE_ID,
1338
- texture: new Texture2D({
1339
- gl: this.scene.canvas.gl,
1340
- preloadColor: [0, 0, 0, 0] // [x, y, z, unused] - these must be zeros
1341
- })
1342
- });
1343
- const defaultEmissiveTexture = new SceneModelTexture({
1344
- id: DEFAULT_EMISSIVE_TEXTURE_ID,
1345
- texture: new Texture2D({
1346
- gl: this.scene.canvas.gl,
1347
- preloadColor: [0, 0, 0, 1] // [x, y, z, unused]
1348
- })
1349
- });
1350
- const defaultOcclusionTexture = new SceneModelTexture({
1351
- id: DEFAULT_OCCLUSION_TEXTURE_ID,
1352
- texture: new Texture2D({
1353
- gl: this.scene.canvas.gl,
1354
- preloadColor: [1, 1, 1, 1] // [x, y, z, unused]
1355
- })
1356
- });
1357
- this._textures[DEFAULT_COLOR_TEXTURE_ID] = defaultColorTexture;
1358
- this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID] = defaultMetalRoughTexture;
1359
- this._textures[DEFAULT_NORMALS_TEXTURE_ID] = defaultNormalsTexture;
1360
- this._textures[DEFAULT_EMISSIVE_TEXTURE_ID] = defaultEmissiveTexture;
1361
- this._textures[DEFAULT_OCCLUSION_TEXTURE_ID] = defaultOcclusionTexture;
1362
- this._textureSets[DEFAULT_TEXTURE_SET_ID] = new SceneModelTextureSet({
1363
- id: DEFAULT_TEXTURE_SET_ID,
1364
- model: this,
1365
- colorTexture: defaultColorTexture,
1366
- metallicRoughnessTexture: defaultMetalRoughTexture,
1367
- normalsTexture: defaultNormalsTexture,
1368
- emissiveTexture: defaultEmissiveTexture,
1369
- occlusionTexture: defaultOcclusionTexture
1370
- });
1371
- }
1372
-
1373
1329
  //------------------------------------------------------------------------------------------------------------------
1374
1330
  // SceneModel members
1375
1331
  //------------------------------------------------------------------------------------------------------------------
@@ -2272,6 +2228,14 @@ export class SceneModel extends Component {
2272
2228
  }
2273
2229
  }
2274
2230
 
2231
+ _createDefaultIndices(numIndices) {
2232
+ const indices = [];
2233
+ for (let i = 0; i < numIndices; i++) {
2234
+ indices.push(i);
2235
+ }
2236
+ return indices;
2237
+ }
2238
+
2275
2239
  /**
2276
2240
  * Creates a reusable geometry within this SceneModel.
2277
2241
  *
@@ -2327,8 +2291,7 @@ export class SceneModel extends Component {
2327
2291
  return null;
2328
2292
  }
2329
2293
  if (!cfg.buckets && !cfg.indices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
2330
- const numPositions = (cfg.positions || cfg.positionsCompressed).length / 3;
2331
- cfg.indices = this._createDefaultIndices(numPositions);
2294
+ cfg.indices = this._createDefaultIndices((cfg.positions || cfg.positionsCompressed).length / 3);
2332
2295
  }
2333
2296
  if (!cfg.buckets && !cfg.indices && cfg.primitive !== "points") {
2334
2297
  this.error(`[createGeometry] Param expected: indices (required for '${cfg.primitive}' primitive type)`);
@@ -2580,74 +2543,39 @@ export class SceneModel extends Component {
2580
2543
  const textureSetId = cfg.id;
2581
2544
  if (textureSetId === undefined || textureSetId === null) {
2582
2545
  this.error("[createTextureSet] Config missing: id");
2583
- return;
2546
+ return false;
2584
2547
  }
2585
2548
  if (this._textureSets[textureSetId]) {
2586
2549
  this.error(`[createTextureSet] Texture set already created: ${textureSetId}`);
2587
- return;
2588
- }
2589
- let colorTexture;
2590
- if (cfg.colorTextureId !== undefined && cfg.colorTextureId !== null) {
2591
- colorTexture = this._textures[cfg.colorTextureId];
2592
- if (!colorTexture) {
2593
- this.error(`[createTextureSet] Texture not found: ${cfg.colorTextureId} - ensure that you create it first with createTexture()`);
2594
- return;
2595
- }
2596
- } else {
2597
- colorTexture = this._textures[DEFAULT_COLOR_TEXTURE_ID];
2598
- }
2599
- let metallicRoughnessTexture;
2600
- if (cfg.metallicRoughnessTextureId !== undefined && cfg.metallicRoughnessTextureId !== null) {
2601
- metallicRoughnessTexture = this._textures[cfg.metallicRoughnessTextureId];
2602
- if (!metallicRoughnessTexture) {
2603
- this.error(`[createTextureSet] Texture not found: ${cfg.metallicRoughnessTextureId} - ensure that you create it first with createTexture()`);
2604
- return;
2605
- }
2606
- } else {
2607
- metallicRoughnessTexture = this._textures[DEFAULT_METAL_ROUGH_TEXTURE_ID];
2608
- }
2609
- let normalsTexture;
2610
- if (cfg.normalsTextureId !== undefined && cfg.normalsTextureId !== null) {
2611
- normalsTexture = this._textures[cfg.normalsTextureId];
2612
- if (!normalsTexture) {
2613
- this.error(`[createTextureSet] Texture not found: ${cfg.normalsTextureId} - ensure that you create it first with createTexture()`);
2614
- return;
2615
- }
2616
- } else {
2617
- normalsTexture = this._textures[DEFAULT_NORMALS_TEXTURE_ID];
2618
- }
2619
- let emissiveTexture;
2620
- if (cfg.emissiveTextureId !== undefined && cfg.emissiveTextureId !== null) {
2621
- emissiveTexture = this._textures[cfg.emissiveTextureId];
2622
- if (!emissiveTexture) {
2623
- this.error(`[createTextureSet] Texture not found: ${cfg.emissiveTextureId} - ensure that you create it first with createTexture()`);
2624
- return;
2625
- }
2626
- } else {
2627
- emissiveTexture = this._textures[DEFAULT_EMISSIVE_TEXTURE_ID];
2550
+ return false;
2628
2551
  }
2629
- let occlusionTexture;
2630
- if (cfg.occlusionTextureId !== undefined && cfg.occlusionTextureId !== null) {
2631
- occlusionTexture = this._textures[cfg.occlusionTextureId];
2632
- if (!occlusionTexture) {
2633
- this.error(`[createTextureSet] Texture not found: ${cfg.occlusionTextureId} - ensure that you create it first with createTexture()`);
2634
- return;
2552
+
2553
+ const getTexture = (cfgId, defaultKey) => {
2554
+ const id = cfgId ?? defaultKey;
2555
+ if (id in this._textures) {
2556
+ return this._textures[id];
2557
+ } else {
2558
+ throw cfgId;
2635
2559
  }
2636
- } else {
2637
- occlusionTexture = this._textures[DEFAULT_OCCLUSION_TEXTURE_ID];
2560
+ };
2561
+
2562
+ try {
2563
+ const textureSet = new SceneModelTextureSet({
2564
+ id: textureSetId,
2565
+ model: this,
2566
+ alphaCutoff: cfg.alphaCutoff,
2567
+ colorTexture: getTexture(cfg.colorTextureId, DEFAULT_COLOR_TEXTURE_ID),
2568
+ metallicRoughnessTexture: getTexture(cfg.metallicRoughnessTextureId, DEFAULT_METAL_ROUGH_TEXTURE_ID),
2569
+ normalsTexture: getTexture(cfg.normalsTextureId, DEFAULT_NORMALS_TEXTURE_ID),
2570
+ emissiveTexture: getTexture(cfg.emissiveTextureId, DEFAULT_EMISSIVE_TEXTURE_ID),
2571
+ occlusionTexture: getTexture(cfg.occlusionTextureId, DEFAULT_OCCLUSION_TEXTURE_ID)
2572
+ });
2573
+ this._textureSets[textureSetId] = textureSet;
2574
+ return textureSet;
2575
+ } catch (id) {
2576
+ this.error(`[createTextureSet] Texture not found: ${id} - ensure that you create it first with createTexture()`);
2577
+ return false;
2638
2578
  }
2639
- const textureSet = new SceneModelTextureSet({
2640
- id: textureSetId,
2641
- model: this,
2642
- colorTexture,
2643
- alphaCutoff: cfg.alphaCutoff,
2644
- metallicRoughnessTexture,
2645
- normalsTexture,
2646
- emissiveTexture,
2647
- occlusionTexture
2648
- });
2649
- this._textureSets[textureSetId] = textureSet;
2650
- return textureSet;
2651
2579
  }
2652
2580
 
2653
2581
  /**
@@ -2750,17 +2678,36 @@ export class SceneModel extends Component {
2750
2678
  return false;
2751
2679
  }
2752
2680
 
2753
- const instancing = (cfg.geometryId !== undefined);
2754
- const batching = !instancing;
2681
+ const geometryId = cfg.geometryId;
2682
+ const instancing = geometryId !== undefined;
2683
+
2684
+ if (instancing) {
2685
+ if (cfg.positions || cfg.positionsCompressed || cfg.indices || cfg.edgeIndices || cfg.normals || cfg.normalsCompressed || cfg.uv || cfg.uvCompressed || cfg.positionsDecodeMatrix) {
2686
+ this.error(`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`);
2687
+ return false;
2688
+ }
2689
+
2690
+ cfg.geometry = this._geometries[geometryId];
2691
+ if (!cfg.geometry) {
2692
+ this.error(`[createMesh] Geometry not found: ${geometryId} - ensure that you create it first with createGeometry()`);
2693
+ return false;
2694
+ }
2695
+ } else {
2696
+ cfg.primitive ??= "triangles";
2697
+ }
2698
+
2699
+ const primitive = instancing ? cfg.geometry.primitive : cfg.primitive;
2700
+ const isTriangular = (primitive === "triangles") || (primitive === "solid") || (primitive === "surface");
2701
+ const textureSetId = cfg.textureSetId;
2702
+ const useDTX = this._dtxEnabled && isTriangular && (! textureSetId);
2703
+
2704
+ cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
2755
2705
 
2756
- if (batching) {
2706
+ if (! instancing) {
2757
2707
 
2758
2708
  // Batched geometry
2759
2709
 
2760
- if (cfg.primitive === undefined || cfg.primitive === null) {
2761
- cfg.primitive = "triangles";
2762
- }
2763
- if (cfg.primitive !== "points" && cfg.primitive !== "lines" && cfg.primitive !== "triangles" && cfg.primitive !== "solid" && cfg.primitive !== "surface") {
2710
+ if (primitive !== "points" && primitive !== "lines" && primitive !== "triangles" && primitive !== "solid" && primitive !== "surface") {
2764
2711
  this.error(`Unsupported value for 'primitive': '${primitive}' ('geometryId' is absent) - supported values are 'points', 'lines', 'triangles', 'solid' and 'surface'.`);
2765
2712
  return false;
2766
2713
  }
@@ -2780,27 +2727,19 @@ export class SceneModel extends Component {
2780
2727
  this.error("Param expected: 'uvCompressed' should be accompanied by `uvDecodeMatrix` ('geometryId' is absent)");
2781
2728
  return false;
2782
2729
  }
2783
- if (!cfg.buckets && !cfg.indices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
2784
- const numPositions = (cfg.positions || cfg.positionsCompressed).length / 3;
2785
- cfg.indices = this._createDefaultIndices(numPositions);
2786
- }
2787
- if (!cfg.buckets && !cfg.indices && cfg.primitive !== "points") {
2788
- cfg.indices = this._createDefaultIndices(numIndices)
2789
- this.error(`Param expected: indices (required for '${cfg.primitive}' primitive type)`);
2790
- return false;
2730
+ if (!cfg.buckets && !cfg.indices) {
2731
+ if (isTriangular) {
2732
+ cfg.indices = this._createDefaultIndices((cfg.positions || cfg.positionsCompressed).length / 3);
2733
+ } else if (primitive === "lines") {
2734
+ this.error(`Param expected: indices (required for '${primitive}' primitive type)`);
2735
+ return false;
2736
+ }
2791
2737
  }
2792
2738
  if ((cfg.matrix || cfg.position || cfg.rotation || cfg.scale) && (cfg.positionsCompressed || cfg.positionsDecodeBoundary)) {
2793
2739
  this.error("Unexpected params: 'matrix', 'rotation', 'scale', 'position' not allowed with 'positionsCompressed'");
2794
2740
  return false;
2795
2741
  }
2796
2742
 
2797
- const useDTX = (!!this._dtxEnabled && (cfg.primitive === "triangles"
2798
- || cfg.primitive === "solid"
2799
- || cfg.primitive === "surface"))
2800
- && (!cfg.textureSetId);
2801
-
2802
- cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
2803
-
2804
2743
  // MATRIX - optional for batching
2805
2744
 
2806
2745
  if (cfg.matrix) {
@@ -2808,194 +2747,86 @@ export class SceneModel extends Component {
2808
2747
  } else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {
2809
2748
  const scale = cfg.scale || DEFAULT_SCALE;
2810
2749
  const position = cfg.position || DEFAULT_POSITION;
2811
- if (cfg.rotation) {
2812
- math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion);
2813
- cfg.meshMatrix = math.composeMat4(position, tempQuaternion, scale, math.mat4());
2814
- } else {
2815
- cfg.meshMatrix = math.composeMat4(position, cfg.quaternion || DEFAULT_QUATERNION, scale, math.mat4());
2816
- }
2750
+ const quaternion = (cfg.rotation
2751
+ ? math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion)
2752
+ : cfg.quaternion || DEFAULT_QUATERNION);
2753
+ cfg.meshMatrix = math.composeMat4(position, quaternion, scale, math.mat4());
2817
2754
  }
2818
2755
 
2819
2756
  if (cfg.positionsDecodeBoundary) {
2820
2757
  cfg.positionsDecodeMatrix = createPositionsDecodeMatrix(cfg.positionsDecodeBoundary, math.mat4());
2821
2758
  }
2822
2759
 
2823
- if (useDTX) {
2760
+ // RTC && COMPRESSION
2824
2761
 
2825
- // DTX
2826
-
2827
- cfg.type = DTX;
2828
-
2829
- // NPR
2830
-
2831
- cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;
2832
- cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
2833
-
2834
- // RTC
2835
-
2836
- if (cfg.positions) {
2837
- const rtcCenter = math.vec3();
2838
- const rtcPositions = [];
2839
- const rtcNeeded = worldToRTCPositions(cfg.positions, rtcPositions, rtcCenter);
2840
- if (rtcNeeded) {
2841
- cfg.positions = rtcPositions;
2842
- cfg.origin = math.addVec3(cfg.origin, rtcCenter, rtcCenter);
2843
- }
2762
+ if (cfg.positions) {
2763
+ const rtcPositions = [];
2764
+ const rtcNeeded = worldToRTCPositions(cfg.positions, rtcPositions, tempVec3a);
2765
+ if (rtcNeeded) {
2766
+ cfg.positions = rtcPositions;
2767
+ cfg.origin = math.addVec3(cfg.origin, tempVec3a, math.vec3());
2844
2768
  }
2845
2769
 
2846
- // COMPRESSION
2847
-
2848
- if (cfg.positions) {
2849
- const aabb = math.collapseAABB3();
2770
+ const aabb = math.collapseAABB3();
2771
+ if (useDTX) {
2850
2772
  cfg.positionsDecodeMatrix = math.mat4();
2851
2773
  math.expandAABB3Points3(aabb, cfg.positions);
2852
2774
  cfg.positionsCompressed = quantizePositions(cfg.positions, aabb, cfg.positionsDecodeMatrix);
2853
- cfg.aabb = aabb;
2854
-
2855
- } else if (cfg.positionsCompressed) {
2856
- const aabb = math.collapseAABB3();
2857
- math.expandAABB3Points3(aabb, cfg.positionsCompressed);
2858
- geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
2859
- cfg.aabb = aabb;
2860
-
2861
- }
2862
- if (cfg.buckets) {
2863
- const aabb = math.collapseAABB3();
2864
- for (let i = 0, len = cfg.buckets.length; i < len; i++) {
2865
- const bucket = cfg.buckets[i];
2866
- if (bucket.positions) {
2867
- math.expandAABB3Points3(aabb, bucket.positions);
2868
- } else if (bucket.positionsCompressed) {
2869
- math.expandAABB3Points3(aabb, bucket.positionsCompressed);
2870
- }
2871
- }
2872
- if (cfg.positionsDecodeMatrix) {
2873
- geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
2874
- }
2875
- cfg.aabb = aabb;
2876
- }
2877
-
2878
- if (cfg.meshMatrix) {
2879
- math.AABB3ToOBB3(cfg.aabb, tempOBB3);
2880
- math.transformOBB3(cfg.meshMatrix, tempOBB3);
2881
- math.OBB3ToAABB3(tempOBB3, cfg.aabb);
2882
- }
2883
-
2884
- // EDGES
2885
-
2886
- if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
2887
- if (cfg.positions) { // Faster
2888
- cfg.edgeIndices = buildEdgeIndices(cfg.positions, cfg.indices, null, 2.0);
2889
- } else {
2890
- cfg.edgeIndices = buildEdgeIndices(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);
2891
- }
2892
- }
2893
-
2894
- // BUCKETING
2895
-
2896
- if (!cfg.buckets) {
2897
- cfg.buckets = createDTXBuckets(cfg, this._enableVertexWelding && this._enableIndexBucketing);
2898
- }
2899
-
2900
- } else {
2901
-
2902
- // VBO
2903
-
2904
- cfg.type = VBO_BATCHED;
2905
-
2906
- // PBR
2907
-
2908
- cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : [255, 255, 255];
2909
- cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
2910
- cfg.metallic = (cfg.metallic !== undefined && cfg.metallic !== null) ? Math.floor(cfg.metallic * 255) : 0;
2911
- cfg.roughness = (cfg.roughness !== undefined && cfg.roughness !== null) ? Math.floor(cfg.roughness * 255) : 255;
2912
-
2913
- // RTC
2914
-
2915
- if (cfg.positions) {
2916
- const rtcPositions = [];
2917
- const rtcNeeded = worldToRTCPositions(cfg.positions, rtcPositions, tempVec3a);
2918
- if (rtcNeeded) {
2919
- cfg.positions = rtcPositions;
2920
- cfg.origin = math.addVec3(cfg.origin, tempVec3a, math.vec3());
2921
- }
2922
- }
2923
-
2924
- if (cfg.positions) {
2925
- const aabb = math.collapseAABB3();
2775
+ } else {
2926
2776
  if (cfg.meshMatrix) {
2927
2777
  math.transformPositions3(cfg.meshMatrix, cfg.positions, cfg.positions);
2928
2778
  cfg.meshMatrix = null; // Positions now baked, don't need any more
2929
2779
  }
2930
2780
  math.expandAABB3Points3(aabb, cfg.positions);
2931
- cfg.aabb = aabb;
2932
-
2933
- } else {
2934
- const aabb = math.collapseAABB3();
2935
- math.expandAABB3Points3(aabb, cfg.positionsCompressed);
2936
- geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
2937
- cfg.aabb = aabb;
2938
- }
2939
-
2940
- if (cfg.meshMatrix) {
2941
- math.AABB3ToOBB3(cfg.aabb, tempOBB3);
2942
- math.transformOBB3(cfg.meshMatrix, tempOBB3);
2943
- math.OBB3ToAABB3(tempOBB3, cfg.aabb);
2944
2781
  }
2782
+ cfg.aabb = aabb;
2783
+ } else if (cfg.positionsCompressed) {
2784
+ const aabb = math.collapseAABB3();
2785
+ math.expandAABB3Points3(aabb, cfg.positionsCompressed);
2786
+ geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
2787
+ cfg.aabb = aabb;
2788
+ }
2945
2789
 
2946
- // EDGES
2947
-
2948
- if (!cfg.buckets && !cfg.edgeIndices && (cfg.primitive === "triangles" || cfg.primitive === "solid" || cfg.primitive === "surface")) {
2949
- if (cfg.positions) {
2950
- cfg.edgeIndices = buildEdgeIndices(cfg.positions, cfg.indices, null, 2.0);
2951
- } else {
2952
- cfg.edgeIndices = buildEdgeIndices(cfg.positionsCompressed, cfg.indices, cfg.positionsDecodeMatrix, 2.0);
2790
+ if (useDTX && cfg.buckets) {
2791
+ const aabb = math.collapseAABB3();
2792
+ cfg.buckets.forEach(bucket => {
2793
+ const positions = bucket.positions || bucket.positionsCompressed;
2794
+ if (positions) {
2795
+ math.expandAABB3Points3(aabb, positions);
2953
2796
  }
2797
+ });
2798
+ if (cfg.positionsDecodeMatrix) {
2799
+ geometryCompressionUtils.decompressAABB(aabb, cfg.positionsDecodeMatrix);
2954
2800
  }
2801
+ cfg.aabb = aabb;
2802
+ }
2955
2803
 
2956
- // TEXTURE
2804
+ // EDGES
2957
2805
 
2958
- // cfg.textureSetId = cfg.textureSetId || DEFAULT_TEXTURE_SET_ID;
2959
- if (cfg.textureSetId) {
2960
- cfg.textureSet = this._textureSets[cfg.textureSetId];
2961
- if (!cfg.textureSet) {
2962
- this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);
2963
- return false;
2964
- }
2965
- }
2806
+ if (isTriangular && (! cfg.buckets)) {
2807
+ cfg.edgeIndices ||= buildEdgeIndices(cfg.positions || cfg.positionsCompressed, cfg.indices, cfg.positions ? null : cfg.positionsDecodeMatrix, 2.0);
2966
2808
  }
2967
2809
 
2968
2810
  } else {
2969
2811
 
2970
2812
  // INSTANCING
2971
2813
 
2972
- if (cfg.positions || cfg.positionsCompressed || cfg.indices || cfg.edgeIndices || cfg.normals || cfg.normalsCompressed || cfg.uv || cfg.uvCompressed || cfg.positionsDecodeMatrix) {
2973
- this.error(`Mesh geometry parameters not expected when instancing a geometry (not expected: positions, positionsCompressed, indices, edgeIndices, normals, normalsCompressed, uv, uvCompressed, positionsDecodeMatrix)`);
2974
- return false;
2975
- }
2976
-
2977
- cfg.geometry = this._geometries[cfg.geometryId];
2978
- if (!cfg.geometry) {
2979
- this.error(`[createMesh] Geometry not found: ${cfg.geometryId} - ensure that you create it first with createGeometry()`);
2980
- return false;
2981
- }
2982
-
2983
- cfg.origin = cfg.origin ? math.addVec3(this._origin, cfg.origin, math.vec3()) : this._origin;
2984
2814
  cfg.positionsDecodeMatrix = cfg.geometry.positionsDecodeMatrix;
2985
2815
 
2986
- if (cfg.transformId) {
2816
+ cfg.aabb = math.AABB3(cfg.geometry.aabb);
2817
+
2818
+ const transformId = cfg.transformId;
2819
+ if (transformId) {
2987
2820
 
2988
2821
  // TRANSFORM
2989
2822
 
2990
- cfg.transform = this._transforms[cfg.transformId];
2823
+ cfg.transform = this._transforms[transformId];
2991
2824
 
2992
2825
  if (!cfg.transform) {
2993
- this.error(`[createMesh] Transform not found: ${cfg.transformId} - ensure that you create it first with createTransform()`);
2826
+ this.error(`[createMesh] Transform not found: ${transformId} - ensure that you create it first with createTransform()`);
2994
2827
  return false;
2995
2828
  }
2996
2829
 
2997
- cfg.aabb = cfg.geometry.aabb;
2998
-
2999
2830
  } else {
3000
2831
 
3001
2832
  // MATRIX
@@ -3005,111 +2836,66 @@ export class SceneModel extends Component {
3005
2836
  } else if (cfg.scale || cfg.rotation || cfg.position || cfg.quaternion) {
3006
2837
  const scale = cfg.scale || DEFAULT_SCALE;
3007
2838
  const position = cfg.position || DEFAULT_POSITION;
3008
- if (cfg.rotation) {
3009
- math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion);
3010
- cfg.meshMatrix = math.composeMat4(position, tempQuaternion, scale, math.mat4());
3011
- } else {
3012
- cfg.meshMatrix = math.composeMat4(position, cfg.quaternion || DEFAULT_QUATERNION, scale, math.mat4());
3013
- }
2839
+ const quaternion = (cfg.rotation
2840
+ ? math.eulerToQuaternion(cfg.rotation, "XYZ", tempQuaternion)
2841
+ : cfg.quaternion || DEFAULT_QUATERNION);
2842
+ cfg.meshMatrix = math.composeMat4(position, quaternion, scale, math.mat4());
3014
2843
  }
3015
-
3016
- math.AABB3ToOBB3(cfg.geometry.aabb, tempOBB3);
3017
- math.transformOBB3(cfg.meshMatrix, tempOBB3);
3018
- cfg.aabb = math.OBB3ToAABB3(tempOBB3, math.AABB3());
3019
2844
  }
2845
+ }
3020
2846
 
3021
- const useDTX = (!!this._dtxEnabled
3022
- && (cfg.geometry.primitive === "triangles"
3023
- || cfg.geometry.primitive === "solid"
3024
- || cfg.geometry.primitive === "surface"))
3025
- && (!cfg.textureSetId);
3026
-
3027
- if (useDTX) {
3028
-
3029
- // DTX
3030
-
3031
- cfg.type = DTX;
3032
-
3033
- // NPR
2847
+ if (cfg.meshMatrix) {
2848
+ math.AABB3ToOBB3(cfg.aabb, tempOBB3);
2849
+ math.transformOBB3(cfg.meshMatrix, tempOBB3, tempOBB3);
2850
+ math.OBB3ToAABB3(tempOBB3, cfg.aabb);
2851
+ }
3034
2852
 
3035
- cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;
3036
- cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
2853
+ cfg.color = cfg.color ? new Uint8Array(cfg.color.slice(0, 3).map(v => Math.floor(v * 255))) : defaultCompressedColor;
2854
+ cfg.opacity = Math.floor((cfg.opacity ?? 1) * 255);
3037
2855
 
3038
- // BUCKETING - lazy generated, reused
2856
+ if (useDTX) {
2857
+ cfg.type = DTX;
3039
2858
 
3040
- let buckets = this._dtxBuckets[cfg.geometryId];
3041
- if (!buckets) {
3042
- buckets = createDTXBuckets(cfg.geometry, this._enableVertexWelding, this._enableIndexBucketing);
3043
- this._dtxBuckets[cfg.geometryId] = buckets;
2859
+ // BUCKETING
2860
+ if (instancing) {
2861
+ cfg.buckets = this._dtxBuckets[geometryId]; // lazy generated, reused
2862
+ }
2863
+ if (!cfg.buckets) {
2864
+ cfg.buckets = createDTXBuckets(instancing ? cfg.geometry : cfg, this._enableVertexWelding, this._enableIndexBucketing);
2865
+ if (instancing) {
2866
+ this._dtxBuckets[geometryId] = cfg.buckets;
3044
2867
  }
3045
- cfg.buckets = buckets;
3046
-
3047
- } else {
3048
-
3049
- // VBO
3050
-
3051
- cfg.type = VBO_INSTANCED;
3052
-
3053
- // PBR
3054
-
3055
- cfg.color = (cfg.color) ? new Uint8Array([Math.floor(cfg.color[0] * 255), Math.floor(cfg.color[1] * 255), Math.floor(cfg.color[2] * 255)]) : defaultCompressedColor;
3056
- cfg.opacity = (cfg.opacity !== undefined && cfg.opacity !== null) ? Math.floor(cfg.opacity * 255) : 255;
3057
- cfg.metallic = (cfg.metallic !== undefined && cfg.metallic !== null) ? Math.floor(cfg.metallic * 255) : 0;
3058
- cfg.roughness = (cfg.roughness !== undefined && cfg.roughness !== null) ? Math.floor(cfg.roughness * 255) : 255;
3059
-
3060
- // TEXTURE
2868
+ }
3061
2869
 
3062
- if (cfg.textureSetId) {
3063
- cfg.textureSet = this._textureSets[cfg.textureSetId];
3064
- // if (!cfg.textureSet) {
3065
- // this.error(`[createMesh] Texture set not found: ${cfg.textureSetId} - ensure that you create it first with createTextureSet()`);
3066
- // return false;
3067
- // }
2870
+ } else {
2871
+ cfg.type = instancing ? VBO_INSTANCED : VBO_BATCHED;
2872
+
2873
+ // PBR
2874
+ cfg.metallic = Math.floor((cfg.metallic ?? 0) * 255);
2875
+ cfg.roughness = Math.floor((cfg.roughness ?? 1) * 255);
2876
+
2877
+ // TEXTURE
2878
+ // cfg.textureSetId = cfg.textureSetId || DEFAULT_TEXTURE_SET_ID;
2879
+ if (textureSetId) {
2880
+ cfg.textureSet = this._textureSets[textureSetId];
2881
+ if ((! instancing) && (!cfg.textureSet)) {
2882
+ this.error(`[createMesh] Texture set not found: ${textureSetId} - ensure that you create it first with createTextureSet()`);
2883
+ return false;
3068
2884
  }
3069
2885
  }
3070
2886
  }
3071
2887
 
3072
2888
  cfg.numPrimitives = this._getNumPrimitives(cfg);
3073
2889
 
3074
- return this._createMesh(cfg);
3075
- }
3076
-
3077
- _createDefaultIndices(numIndices) {
3078
- const indices = [];
3079
- for (let i = 0; i < numIndices; i++) {
3080
- indices.push(i);
3081
- }
3082
- return indices;
3083
- }
3084
-
3085
- _createMesh(cfg) {
3086
2890
  const mesh = new SceneModelMesh(this, cfg.id, cfg.color, cfg.opacity, cfg.transform, cfg.textureSet);
3087
- mesh.pickId = this.scene._renderer.getPickID(mesh);
3088
- const pickId = mesh.pickId;
3089
- const a = pickId >> 24 & 0xFF;
3090
- const b = pickId >> 16 & 0xFF;
3091
- const g = pickId >> 8 & 0xFF;
3092
- const r = pickId & 0xFF;
3093
- cfg.pickColor = new Uint8Array([r, g, b, a]); // Quantized pick color
3094
- cfg.solid = (cfg.primitive === "solid");
2891
+ const pickId = this.scene._renderer.getPickID(mesh);
2892
+ mesh.pickId = pickId;
3095
2893
  mesh.origin = math.vec3(cfg.origin);
3096
- switch (cfg.type) {
3097
- case DTX:
3098
- mesh.layer = this._getDTXLayer(cfg);
3099
- mesh.aabb = cfg.aabb;
3100
- break;
3101
- case VBO_BATCHED:
3102
- mesh.layer = this._getVBOBatchingLayer(cfg);
3103
- mesh.aabb = cfg.aabb;
3104
- break;
3105
- case VBO_INSTANCED:
3106
- mesh.layer = this._getVBOInstancingLayer(cfg);
3107
- mesh.aabb = cfg.aabb;
3108
- break;
3109
- }
3110
- if (cfg.transform) {
3111
- cfg.meshMatrix = cfg.transform.worldMatrix;
3112
- }
2894
+ mesh.layer = (cfg.type === DTX) ? this._getDTXLayer(cfg) : this._getVBOLayer(cfg.type === VBO_INSTANCED, cfg);
2895
+ mesh.aabb = cfg.aabb;
2896
+ cfg.pickColor = new Uint8Array([pickId & 0xFF, pickId >> 8 & 0xFF, pickId >> 16 & 0xFF, pickId >> 24 & 0xFF]); // Quantized pick color
2897
+ cfg.solid = (cfg.primitive === "solid");
2898
+ cfg.meshMatrix = cfg.transform ? cfg.transform.worldMatrix : cfg.meshMatrix;
3113
2899
  mesh.portionId = mesh.layer.createPortion(mesh, cfg);
3114
2900
  mesh.numPrimitives = cfg.numPrimitives;
3115
2901
  this._meshes[cfg.id] = mesh;
@@ -3193,10 +2979,7 @@ export class SceneModel extends Component {
3193
2979
  case "triangles":
3194
2980
  case "solid":
3195
2981
  case "surface":
3196
- dtxLayer = new DTXTrianglesLayer(this, {layerIndex: 0, origin, primitive}); // layerIndex is set in #finalize()
3197
- break;
3198
- case "lines":
3199
- dtxLayer = new DTXLinesLayer(this, {layerIndex: 0, origin, primitive}); // layerIndex is set in #finalize()
2982
+ dtxLayer = new DTXLayer(this, primitive, origin);
3200
2983
  break;
3201
2984
  default:
3202
2985
  return;
@@ -3207,204 +2990,41 @@ export class SceneModel extends Component {
3207
2990
  return dtxLayer;
3208
2991
  }
3209
2992
 
3210
- _getVBOBatchingLayer(cfg) {
3211
- const model = this;
2993
+ _getVBOLayer(instancing, cfg) {
2994
+ const geometry = instancing && cfg.geometry;
2995
+ const primitive = instancing ? geometry.primitive : cfg.primitive;
3212
2996
  const origin = cfg.origin;
3213
- const renderLayer = cfg.renderLayer || 0;
3214
- const positionsDecodeHash = cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary ?
3215
- this._createHashStringFromMatrix(cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary)
3216
- : "-";
2997
+ const posDecode = (! instancing) && (cfg.positionsDecodeMatrix || cfg.positionsDecodeBoundary);
2998
+ const positionsDecodeHash = posDecode ? (JSON.stringify(posDecode).split("").reduce((hash, char) => (((hash << 5) - hash + char.charCodeAt(0)) | 0), 0) >>> 0).toString(16) : "-";
3217
2999
  const textureSetId = cfg.textureSetId || "-";
3218
- const layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${cfg.primitive}.${positionsDecodeHash}.${textureSetId}`;
3219
- let vboBatchingLayer = this._vboBatchingLayers[layerId];
3220
- if (vboBatchingLayer) {
3221
- return vboBatchingLayer;
3222
- }
3223
- let textureSet = cfg.textureSet;
3224
- while (!vboBatchingLayer) {
3225
- switch (cfg.primitive) {
3226
- case "triangles":
3227
- // console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);
3228
- vboBatchingLayer = new VBOBatchingTrianglesLayer({
3229
- model,
3230
- textureSet,
3231
- layerIndex: 0, // This is set in #finalize()
3232
- scratchMemory: this._vboBatchingLayerScratchMemory,
3233
- positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
3234
- uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
3235
- origin,
3236
- maxGeometryBatchSize: this._maxGeometryBatchSize,
3237
- solid: (cfg.primitive === "solid"),
3238
- autoNormals: true,
3239
- primitive: cfg.primitive
3240
- });
3241
- break;
3242
- case "solid":
3243
- // console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);
3244
- vboBatchingLayer = new VBOBatchingTrianglesLayer({
3245
- model,
3246
- textureSet,
3247
- layerIndex: 0, // This is set in #finalize()
3248
- scratchMemory: this._vboBatchingLayerScratchMemory,
3249
- positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
3250
- uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
3251
- origin,
3252
- maxGeometryBatchSize: this._maxGeometryBatchSize,
3253
- solid: (cfg.primitive === "solid"),
3254
- autoNormals: true,
3255
- primitive: cfg.primitive
3256
- });
3257
- break;
3258
- case "surface":
3259
- // console.info(`[SceneModel ${this.id}]: creating TrianglesBatchingLayer`);
3260
- vboBatchingLayer = new VBOBatchingTrianglesLayer({
3261
- model,
3262
- textureSet,
3263
- layerIndex: 0, // This is set in #finalize()
3264
- scratchMemory: this._vboBatchingLayerScratchMemory,
3265
- positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
3266
- uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
3267
- origin,
3268
- maxGeometryBatchSize: this._maxGeometryBatchSize,
3269
- solid: (cfg.primitive === "solid"),
3270
- autoNormals: true,
3271
- primitive: cfg.primitive
3272
- });
3273
- break;
3274
- case "lines":
3275
- // console.info(`[SceneModel ${this.id}]: creating VBOBatchingLinesLayer`);
3276
- vboBatchingLayer = new VBOBatchingLinesLayer({
3277
- model,
3278
- layerIndex: 0, // This is set in #finalize()
3279
- scratchMemory: this._vboBatchingLayerScratchMemory,
3280
- positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
3281
- uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
3282
- origin,
3283
- maxGeometryBatchSize: this._maxGeometryBatchSize,
3284
- primitive: cfg.primitive
3285
- });
3286
- break;
3287
- case "points":
3288
- // console.info(`[SceneModel ${this.id}]: creating VBOBatchingPointsLayer`);
3289
- vboBatchingLayer = new VBOBatchingPointsLayer({
3290
- model,
3291
- layerIndex: 0, // This is set in #finalize()
3292
- scratchMemory: this._vboBatchingLayerScratchMemory,
3293
- positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
3294
- uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
3295
- origin,
3296
- maxGeometryBatchSize: this._maxGeometryBatchSize,
3297
- primitive: cfg.primitive
3298
- });
3299
- break;
3300
- }
3000
+ const geometryId = instancing ? cfg.geometryId : "-";
3001
+ const layerId = (instancing ? "instancing" : "batching") + `.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${primitive}.${positionsDecodeHash}.${textureSetId}.${geometryId}`;
3002
+
3003
+ if ((! instancing) && (layerId in this._vboLayers)) {
3004
+ const layer = this._vboLayers[layerId];
3301
3005
  const lenPositions = cfg.positionsCompressed ? cfg.positionsCompressed.length : cfg.positions.length;
3302
- const canCreatePortion = (cfg.primitive === "points")
3303
- ? vboBatchingLayer.canCreatePortion(lenPositions)
3304
- : vboBatchingLayer.canCreatePortion(lenPositions, cfg.indices.length);
3305
- if (!canCreatePortion) {
3306
- vboBatchingLayer.finalize();
3307
- delete this._vboBatchingLayers[layerId];
3308
- vboBatchingLayer = null;
3006
+ if (! layer.canCreatePortion(lenPositions, (primitive === "points") ? 0 : cfg.indices.length)) {
3007
+ layer.finalize();
3008
+ delete this._vboLayers[layerId];
3309
3009
  }
3310
3010
  }
3311
- this._vboBatchingLayers[layerId] = vboBatchingLayer;
3312
- this.layerList.push(vboBatchingLayer);
3313
- this._layersToFinalize.push(vboBatchingLayer);
3314
- return vboBatchingLayer;
3315
- }
3316
-
3317
- _createHashStringFromMatrix(matrix) {
3318
- const matrixString = matrix.join('');
3319
- let hash = 0;
3320
- for (let i = 0; i < matrixString.length; i++) {
3321
- const char = matrixString.charCodeAt(i);
3322
- hash = (hash << 5) - hash + char;
3323
- hash |= 0; // Convert to 32-bit integer
3324
- }
3325
- const hashString = (hash >>> 0).toString(16);
3326
- return hashString;
3327
- }
3328
3011
 
3329
- _getVBOInstancingLayer(cfg) {
3330
- const model = this;
3331
- const origin = cfg.origin;
3332
- const textureSetId = cfg.textureSetId || "-";
3333
- const geometryId = cfg.geometryId;
3334
- const layerId = `${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}.${textureSetId}.${geometryId}`;
3335
- let vboInstancingLayer = this._vboInstancingLayers[layerId];
3336
- if (vboInstancingLayer) {
3337
- return vboInstancingLayer;
3338
- }
3339
- let textureSet = cfg.textureSet;
3340
- const geometry = cfg.geometry;
3341
- while (!vboInstancingLayer) {
3342
- switch (geometry.primitive) {
3343
- case "triangles":
3344
- // console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);
3345
- vboInstancingLayer = new VBOInstancingTrianglesLayer({
3346
- model,
3347
- textureSet,
3348
- geometry,
3349
- origin,
3350
- layerIndex: 0,
3351
- solid: false
3352
- });
3353
- break;
3354
- case "solid":
3355
- // console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);
3356
- vboInstancingLayer = new VBOInstancingTrianglesLayer({
3357
- model,
3358
- textureSet,
3359
- geometry,
3360
- origin,
3361
- layerIndex: 0,
3362
- solid: true
3363
- });
3364
- break;
3365
- case "surface":
3366
- // console.info(`[SceneModel ${this.id}]: creating TrianglesInstancingLayer`);
3367
- vboInstancingLayer = new VBOInstancingTrianglesLayer({
3368
- model,
3369
- textureSet,
3370
- geometry,
3371
- origin,
3372
- layerIndex: 0,
3373
- solid: false
3374
- });
3375
- break;
3376
- case "lines":
3377
- // console.info(`[SceneModel ${this.id}]: creating VBOInstancingLinesLayer`);
3378
- vboInstancingLayer = new VBOInstancingLinesLayer({
3379
- model,
3380
- textureSet,
3381
- geometry,
3382
- origin,
3383
- layerIndex: 0
3384
- });
3385
- break;
3386
- case "points":
3387
- // console.info(`[SceneModel ${this.id}]: creating PointsInstancingLayer`);
3388
- vboInstancingLayer = new VBOInstancingPointsLayer({
3389
- model,
3390
- textureSet,
3391
- geometry,
3392
- origin,
3393
- layerIndex: 0
3394
- });
3395
- break;
3396
- }
3397
- // const lenPositions = geometry.positionsCompressed.length;
3398
- // if (!vboInstancingLayer.canCreatePortion(lenPositions, geometry.indices.length)) { // FIXME: indices should be optional
3399
- // vboInstancingLayer.finalize();
3400
- // delete this._vboInstancingLayers[layerId];
3401
- // vboInstancingLayer = null;
3402
- // }
3012
+ if (! (layerId in this._vboLayers)) {
3013
+ const layer = new VBOLayer(this, primitive, origin, {
3014
+ textureSet: cfg.textureSet,
3015
+ ...(instancing ? {
3016
+ geometry: geometry,
3017
+ } : {
3018
+ maxGeometryBatchSize: this._maxGeometryBatchSize,
3019
+ positionsDecodeMatrix: cfg.positionsDecodeMatrix, // Can be undefined
3020
+ uvDecodeMatrix: cfg.uvDecodeMatrix, // Can be undefined
3021
+ })
3022
+ });
3023
+ this.layerList.push(layer);
3024
+ this._layersToFinalize.push(layer);
3025
+ this._vboLayers[layerId] = layer;
3403
3026
  }
3404
- this._vboInstancingLayers[layerId] = vboInstancingLayer;
3405
- this.layerList.push(vboInstancingLayer);
3406
- this._layersToFinalize.push(vboInstancingLayer);
3407
- return vboInstancingLayer;
3027
+ return this._vboLayers[layerId];
3408
3028
  }
3409
3029
 
3410
3030
  /**
@@ -3444,41 +3064,22 @@ export class SceneModel extends Component {
3444
3064
  }
3445
3065
  if (cfg.meshIds === undefined) {
3446
3066
  this.error("Config missing: meshIds");
3447
- return;
3067
+ return null;
3448
3068
  }
3069
+
3070
+ const notFalse = v => v !== false;
3449
3071
  let flags = 0;
3450
- if (this._visible && cfg.visible !== false) {
3451
- flags = flags | ENTITY_FLAGS.VISIBLE;
3452
- }
3453
- if (this._pickable && cfg.pickable !== false) {
3454
- flags = flags | ENTITY_FLAGS.PICKABLE;
3455
- }
3456
- if (this._culled && cfg.culled !== false) {
3457
- flags = flags | ENTITY_FLAGS.CULLED;
3458
- }
3459
- if (this._clippable && cfg.clippable !== false) {
3460
- flags = flags | ENTITY_FLAGS.CLIPPABLE;
3461
- }
3462
- if (this._collidable && cfg.collidable !== false) {
3463
- flags = flags | ENTITY_FLAGS.COLLIDABLE;
3464
- }
3465
- if (this._edges && cfg.edges !== false) {
3466
- flags = flags | ENTITY_FLAGS.EDGES;
3467
- }
3468
- if (this._xrayed && cfg.xrayed !== false) {
3469
- flags = flags | ENTITY_FLAGS.XRAYED;
3470
- }
3471
- if (this._highlighted && cfg.highlighted !== false) {
3472
- flags = flags | ENTITY_FLAGS.HIGHLIGHTED;
3473
- }
3474
- if (this._selected && cfg.selected !== false) {
3475
- flags = flags | ENTITY_FLAGS.SELECTED;
3476
- }
3072
+ flags |= (this._visible && notFalse(cfg.visible) && ENTITY_FLAGS.VISIBLE);
3073
+ flags |= (this._pickable && notFalse(cfg.pickable) && ENTITY_FLAGS.PICKABLE);
3074
+ flags |= (this._culled && notFalse(cfg.culled) && ENTITY_FLAGS.CULLED);
3075
+ flags |= (this._clippable && notFalse(cfg.clippable) && ENTITY_FLAGS.CLIPPABLE);
3076
+ flags |= (this._collidable && notFalse(cfg.collidable) && ENTITY_FLAGS.COLLIDABLE);
3077
+ flags |= (this._xrayed && notFalse(cfg.xrayed) && ENTITY_FLAGS.XRAYED);
3078
+ flags |= (this._highlighted && notFalse(cfg.highlighted) && ENTITY_FLAGS.HIGHLIGHTED);
3079
+ flags |= (this._selected && notFalse(cfg.selected) && ENTITY_FLAGS.SELECTED);
3080
+ flags |= (this._edges && notFalse(cfg.edges) && ENTITY_FLAGS.EDGES);
3477
3081
  cfg.flags = flags;
3478
- return this._createEntity(cfg);
3479
- }
3480
3082
 
3481
- _createEntity(cfg) {
3482
3083
  let meshes = [];
3483
3084
  for (let i = 0, len = cfg.meshIds.length; i < len; i++) {
3484
3085
  const meshId = cfg.meshIds[i];
@@ -3526,8 +3127,7 @@ export class SceneModel extends Component {
3526
3127
  const layer = this._layersToFinalize[i];
3527
3128
  layer.finalize();
3528
3129
  }
3529
- this._vboBatchingLayers = {};
3530
- this._vboInstancingLayers = {};
3130
+ this._vboLayers = {};
3531
3131
  this._dtxLayers = {};
3532
3132
  this._layersToFinalize = [];
3533
3133
  for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {
@@ -3721,263 +3321,48 @@ export class SceneModel extends Component {
3721
3321
 
3722
3322
  // -------------- RENDERING ---------------------------------------------------------------------------------------
3723
3323
 
3724
- /** @private */
3725
- drawColorOpaque(frameCtx, layerList) {
3726
- const renderFlags = this.renderFlags;
3727
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3728
- const layerIndex = renderFlags.visibleLayers[i];
3729
- this.layerList[layerIndex].drawColorOpaque(renderFlags, frameCtx);
3730
- }
3731
- }
3732
-
3733
- /** @private */
3734
- drawColorTransparent(frameCtx) {
3735
- const renderFlags = this.renderFlags;
3736
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3737
- const layerIndex = renderFlags.visibleLayers[i];
3738
- this.layerList[layerIndex].drawColorTransparent(renderFlags, frameCtx);
3739
- }
3740
- }
3741
-
3742
- /** @private */
3743
- drawDepth(frameCtx) { // Dedicated to SAO because it skips transparent objects
3744
- const renderFlags = this.renderFlags;
3745
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3746
- const layerIndex = renderFlags.visibleLayers[i];
3747
- this.layerList[layerIndex].drawDepth(renderFlags, frameCtx);
3748
- }
3749
- }
3750
-
3751
- /** @private */
3752
- drawNormals(frameCtx) { // Dedicated to SAO because it skips transparent objects
3753
- const renderFlags = this.renderFlags;
3754
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3755
- const layerIndex = renderFlags.visibleLayers[i];
3756
- this.layerList[layerIndex].drawNormals(renderFlags, frameCtx);
3757
- }
3758
- }
3759
-
3760
- /** @private */
3761
- drawSilhouetteXRayed(frameCtx) {
3762
- const renderFlags = this.renderFlags;
3763
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3764
- const layerIndex = renderFlags.visibleLayers[i];
3765
- this.layerList[layerIndex].drawSilhouetteXRayed(renderFlags, frameCtx);
3766
- }
3767
- }
3768
-
3769
- /** @private */
3770
- drawSilhouetteHighlighted(frameCtx) {
3771
- const renderFlags = this.renderFlags;
3772
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3773
- const layerIndex = renderFlags.visibleLayers[i];
3774
- this.layerList[layerIndex].drawSilhouetteHighlighted(renderFlags, frameCtx);
3775
- }
3776
- }
3777
-
3778
- /** @private */
3779
- drawSilhouetteSelected(frameCtx) {
3780
- const renderFlags = this.renderFlags;
3781
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3782
- const layerIndex = renderFlags.visibleLayers[i];
3783
- this.layerList[layerIndex].drawSilhouetteSelected(renderFlags, frameCtx);
3784
- }
3785
- }
3786
-
3787
- /** @private */
3788
- drawEdgesColorOpaque(frameCtx) {
3789
- const renderFlags = this.renderFlags;
3790
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3791
- const layerIndex = renderFlags.visibleLayers[i];
3792
- this.layerList[layerIndex].drawEdgesColorOpaque(renderFlags, frameCtx);
3793
- }
3794
- }
3795
-
3796
- /** @private */
3797
- drawEdgesColorTransparent(frameCtx) {
3798
- const renderFlags = this.renderFlags;
3799
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3800
- const layerIndex = renderFlags.visibleLayers[i];
3801
- this.layerList[layerIndex].drawEdgesColorTransparent(renderFlags, frameCtx);
3802
- }
3803
- }
3804
-
3805
- /** @private */
3806
- drawEdgesXRayed(frameCtx) {
3807
- const renderFlags = this.renderFlags;
3808
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3809
- const layerIndex = renderFlags.visibleLayers[i];
3810
- this.layerList[layerIndex].drawEdgesXRayed(renderFlags, frameCtx);
3811
- }
3812
- }
3813
-
3814
- /** @private */
3815
- drawEdgesHighlighted(frameCtx) {
3816
- const renderFlags = this.renderFlags;
3817
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3818
- const layerIndex = renderFlags.visibleLayers[i];
3819
- this.layerList[layerIndex].drawEdgesHighlighted(renderFlags, frameCtx);
3820
- }
3821
- }
3822
-
3823
- /** @private */
3824
- drawEdgesSelected(frameCtx) {
3825
- const renderFlags = this.renderFlags;
3826
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3827
- const layerIndex = renderFlags.visibleLayers[i];
3828
- this.layerList[layerIndex].drawEdgesSelected(renderFlags, frameCtx);
3829
- }
3830
- }
3831
-
3832
- /**
3833
- * @private
3834
- */
3835
- drawOcclusion(frameCtx) {
3836
- if (this.numVisibleLayerPortions === 0) {
3837
- return;
3838
- }
3839
- const renderFlags = this.renderFlags;
3840
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3841
- const layerIndex = renderFlags.visibleLayers[i];
3842
- this.layerList[layerIndex].drawOcclusion(renderFlags, frameCtx);
3843
- }
3844
- }
3845
-
3846
- /**
3847
- * @private
3848
- */
3849
- drawShadow(frameCtx) {
3850
- if (this.numVisibleLayerPortions === 0) {
3851
- return;
3852
- }
3853
- const renderFlags = this.renderFlags;
3854
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3855
- const layerIndex = renderFlags.visibleLayers[i];
3856
- this.layerList[layerIndex].drawShadow(renderFlags, frameCtx);
3857
- }
3858
- }
3859
-
3860
- /** @private */
3861
- setPickMatrices(pickViewMatrix, pickProjMatrix) {
3862
- if (this._numVisibleLayerPortions === 0) {
3863
- return;
3864
- }
3865
- const renderFlags = this.renderFlags;
3866
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3867
- const layerIndex = renderFlags.visibleLayers[i];
3868
- const layer = this.layerList[layerIndex];
3869
- if (layer.setPickMatrices) {
3870
- layer.setPickMatrices(pickViewMatrix, pickProjMatrix);
3871
- }
3872
- }
3873
- }
3874
-
3875
- /** @private */
3876
- drawPickMesh(frameCtx) {
3877
- if (this.numVisibleLayerPortions === 0) {
3878
- return;
3879
- }
3880
- const renderFlags = this.renderFlags;
3881
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3882
- const layerIndex = renderFlags.visibleLayers[i];
3883
- this.layerList[layerIndex].drawPickMesh(renderFlags, frameCtx);
3884
- }
3885
- }
3886
-
3887
- /**
3888
- * Called by SceneModelMesh.drawPickDepths()
3889
- * @private
3890
- */
3891
- drawPickDepths(frameCtx) {
3892
- if (this.numVisibleLayerPortions === 0) {
3893
- return;
3894
- }
3895
- const renderFlags = this.renderFlags;
3896
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3897
- const layerIndex = renderFlags.visibleLayers[i];
3898
- this.layerList[layerIndex].drawPickDepths(renderFlags, frameCtx);
3899
- }
3900
- }
3901
3324
 
3902
3325
  /**
3903
- * Called by SceneModelMesh.drawPickNormals()
3904
3326
  * @private
3905
3327
  */
3906
- drawPickNormals(frameCtx) {
3907
- if (this.numVisibleLayerPortions === 0) {
3328
+ _withEachVisibleLayer(testNumVisibleLayerPortions, cb) {
3329
+ if (testNumVisibleLayerPortions && (this.numVisibleLayerPortions === 0)) {
3908
3330
  return;
3909
3331
  }
3910
3332
  const renderFlags = this.renderFlags;
3911
3333
  for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3912
3334
  const layerIndex = renderFlags.visibleLayers[i];
3913
- this.layerList[layerIndex].drawPickNormals(renderFlags, frameCtx);
3335
+ cb(this.layerList[layerIndex]);
3914
3336
  }
3915
3337
  }
3916
3338
 
3917
- /**
3918
- * @private
3919
- */
3920
- drawSnapInit(frameCtx) {
3921
- if (this.numVisibleLayerPortions === 0) {
3922
- return;
3923
- }
3924
- const renderFlags = this.renderFlags;
3925
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3926
- const layerIndex = renderFlags.visibleLayers[i];
3927
- const layer = this.layerList[layerIndex];
3928
- if (layer.drawSnapInit) {
3929
- frameCtx.snapPickOrigin = [0, 0, 0];
3930
- frameCtx.snapPickCoordinateScale = [1, 1, 1];
3931
- frameCtx.snapPickLayerNumber++;
3932
- layer.drawSnapInit(renderFlags, frameCtx);
3933
- frameCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {
3934
- origin: frameCtx.snapPickOrigin.slice(),
3935
- coordinateScale: frameCtx.snapPickCoordinateScale.slice(),
3936
- };
3937
- }
3938
- }
3939
- }
3339
+ drawColorOpaque (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawColorOpaque (this.renderFlags, frameCtx)); }
3340
+ drawColorTransparent (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawColorTransparent (this.renderFlags, frameCtx)); }
3341
+ drawDepth (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawDepth (this.renderFlags, frameCtx)); } // Dedicated to SAO because it skips transparent objects
3342
+ drawSilhouetteXRayed (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawSilhouetteXRayed (this.renderFlags, frameCtx)); }
3343
+ drawSilhouetteHighlighted(frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawSilhouetteHighlighted(this.renderFlags, frameCtx)); }
3344
+ drawSilhouetteSelected (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawSilhouetteSelected (this.renderFlags, frameCtx)); }
3345
+ drawEdgesColorOpaque (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesColorOpaque (this.renderFlags, frameCtx)); }
3346
+ drawEdgesColorTransparent(frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesColorTransparent(this.renderFlags, frameCtx)); }
3347
+ drawEdgesXRayed (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesXRayed (this.renderFlags, frameCtx)); }
3348
+ drawEdgesHighlighted (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesHighlighted (this.renderFlags, frameCtx)); }
3349
+ drawEdgesSelected (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesSelected (this.renderFlags, frameCtx)); }
3350
+ drawOcclusion (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawOcclusion (this.renderFlags, frameCtx)); }
3351
+ drawShadow (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawShadow (this.renderFlags, frameCtx)); }
3352
+ drawPickMesh (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawPickMesh (this.renderFlags, frameCtx)); }
3353
+ drawPickDepths (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawPickDepths (this.renderFlags, frameCtx)); }
3354
+ drawPickNormals (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawPickNormals (this.renderFlags, frameCtx)); }
3355
+ _drawSnap (frameCtx, isSnapInit) { this._withEachVisibleLayer(true, layer => layer.drawSnap (this.renderFlags, frameCtx, isSnapInit)); }
3940
3356
 
3941
- /**
3942
- * @private
3943
- */
3944
- drawSnap(frameCtx) {
3945
- if (this.numVisibleLayerPortions === 0) {
3946
- return;
3947
- }
3948
- const renderFlags = this.renderFlags;
3949
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3950
- const layerIndex = renderFlags.visibleLayers[i];
3951
- const layer = this.layerList[layerIndex];
3952
- if (layer.drawSnap) {
3953
- frameCtx.snapPickOrigin = [0, 0, 0];
3954
- frameCtx.snapPickCoordinateScale = [1, 1, 1];
3955
- frameCtx.snapPickLayerNumber++;
3956
- layer.drawSnap(renderFlags, frameCtx);
3957
- frameCtx.snapPickLayerParams[frameCtx.snapPickLayerNumber] = {
3958
- origin: frameCtx.snapPickOrigin.slice(),
3959
- coordinateScale: frameCtx.snapPickCoordinateScale.slice(),
3960
- };
3961
- }
3962
- }
3963
- }
3357
+ drawSnapInit(frameCtx) { this._drawSnap(frameCtx, true ); }
3358
+ drawSnap (frameCtx) { this._drawSnap(frameCtx, false); }
3964
3359
 
3965
3360
  /**
3966
3361
  * Destroys this SceneModel.
3967
3362
  */
3968
3363
  destroy() {
3969
- for (let layerId in this._vboBatchingLayers) {
3970
- if (this._vboBatchingLayers.hasOwnProperty(layerId)) {
3971
- this._vboBatchingLayers[layerId].destroy();
3972
- }
3973
- }
3974
- this._vboBatchingLayers = {};
3975
- for (let layerId in this._vboInstancingLayers) {
3976
- if (this._vboInstancingLayers.hasOwnProperty(layerId)) {
3977
- this._vboInstancingLayers[layerId].destroy();
3978
- }
3979
- }
3980
- this._vboInstancingLayers = {};
3364
+ Object.values(this._vboLayers).forEach(l => l.destroy());
3365
+ this._vboLayers = {};
3981
3366
  this.scene.camera.off(this._onCameraViewMatrix);
3982
3367
  this.scene.off(this._onTick);
3983
3368
  for (let i = 0, len = this.layerList.length; i < len; i++) {
@@ -3987,7 +3372,7 @@ export class SceneModel extends Component {
3987
3372
  for (let i = 0, len = this._entityList.length; i < len; i++) {
3988
3373
  this._entityList[i]._destroy();
3989
3374
  }
3990
- this._layersToFinalize = {};
3375
+ this._layersToFinalize = [];
3991
3376
  // Object.entries(this._geometries).forEach(([id, geometry]) => {
3992
3377
  // geometry.destroy();
3993
3378
  // });
@@ -4001,7 +3386,6 @@ export class SceneModel extends Component {
4001
3386
  if (this._isModel) {
4002
3387
  this.scene._deregisterModel(this);
4003
3388
  }
4004
- putScratchMemory();
4005
3389
  super.destroy();
4006
3390
  }
4007
3391
  }