@xeokit/xeokit-sdk 2.6.92 → 2.6.94

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 (182) hide show
  1. package/dist/xeokit-sdk.cjs.js +13076 -44663
  2. package/dist/xeokit-sdk.es.js +13077 -44662
  3. package/dist/xeokit-sdk.es5.js +1404 -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/viewer/Viewer.js +55 -103
  9. package/src/viewer/scene/canvas/Canvas.js +3 -43
  10. package/src/viewer/scene/geometry/ReadableGeometry.js +0 -25
  11. package/src/viewer/scene/lights/CubeTexture.js +0 -13
  12. package/src/viewer/scene/lights/DirLight.js +3 -2
  13. package/src/viewer/scene/lights/PointLight.js +2 -1
  14. package/src/viewer/scene/materials/Texture.js +0 -9
  15. package/src/viewer/scene/math/rtcCoords.js +1 -38
  16. package/src/viewer/scene/mesh/Mesh.js +454 -212
  17. package/src/viewer/scene/mesh/draw/DrawShaderSource.js +305 -1504
  18. package/src/viewer/scene/mesh/draw/LambertShaderSource.js +35 -0
  19. package/src/viewer/scene/mesh/emphasis/EmphasisShaderSource.js +34 -0
  20. package/src/viewer/scene/mesh/occlusion/OcclusionShaderSource.js +9 -158
  21. package/src/viewer/scene/mesh/pick/PickMeshShaderSource.js +21 -151
  22. package/src/viewer/scene/mesh/pick/PickTriangleShaderSource.js +12 -124
  23. package/src/viewer/scene/mesh/shadow/ShadowShaderSource.js +22 -97
  24. package/src/viewer/scene/model/SceneModel.js +248 -852
  25. package/src/viewer/scene/model/SceneModelEntity.js +4 -4
  26. package/src/viewer/scene/model/SceneModelMesh.js +3 -3
  27. package/src/viewer/scene/model/layer/DTXLayer.js +940 -0
  28. package/src/viewer/scene/model/layer/Layer.js +788 -0
  29. package/src/viewer/scene/model/layer/VBOLayer.js +1019 -0
  30. package/src/viewer/scene/model/layer/programs/ColorProgram.js +35 -0
  31. package/src/viewer/scene/model/layer/programs/ColorTextureProgram.js +46 -0
  32. package/src/viewer/scene/model/layer/programs/DepthProgram.js +11 -0
  33. package/src/viewer/scene/model/layer/programs/EdgesProgram.js +12 -0
  34. package/src/viewer/scene/model/layer/programs/FlatColorProgram.js +24 -0
  35. package/src/viewer/scene/model/layer/programs/OcclusionProgram.js +12 -0
  36. package/src/viewer/scene/model/layer/programs/PBRProgram.js +180 -0
  37. package/src/viewer/scene/model/layer/programs/PickDepthProgram.js +30 -0
  38. package/src/viewer/scene/model/layer/programs/PickMeshProgram.js +12 -0
  39. package/src/viewer/scene/model/layer/programs/PickNormalsProgram.js +18 -0
  40. package/src/viewer/scene/model/layer/programs/ShadowProgram.js +23 -0
  41. package/src/viewer/scene/model/layer/programs/SilhouetteProgram.js +15 -0
  42. package/src/viewer/scene/model/layer/programs/SnapProgram.js +29 -0
  43. package/src/viewer/scene/scene/Scene.js +22 -39
  44. package/src/viewer/scene/webgl/ArrayBuf.js +5 -20
  45. package/src/viewer/scene/webgl/FrameContext.js +14 -86
  46. package/src/viewer/scene/webgl/RenderBuffer.js +62 -262
  47. package/src/viewer/scene/webgl/Renderer.js +880 -843
  48. package/src/viewer/scene/webgl/WebGLRenderer.js +612 -0
  49. package/src/viewer/scene/webgl/occlusion/OcclusionLayer.js +60 -132
  50. package/src/viewer/scene/webgl/occlusion/OcclusionTester.js +167 -328
  51. package/src/viewer/scene/mesh/draw/DrawRenderer.js +0 -998
  52. package/src/viewer/scene/mesh/emphasis/EmphasisEdgesRenderer.js +0 -259
  53. package/src/viewer/scene/mesh/emphasis/EmphasisEdgesShaderSource.js +0 -160
  54. package/src/viewer/scene/mesh/emphasis/EmphasisFillRenderer.js +0 -286
  55. package/src/viewer/scene/mesh/emphasis/EmphasisFillShaderSource.js +0 -263
  56. package/src/viewer/scene/mesh/occlusion/OcclusionRenderer.js +0 -221
  57. package/src/viewer/scene/mesh/pick/PickMeshRenderer.js +0 -223
  58. package/src/viewer/scene/mesh/pick/PickTriangleRenderer.js +0 -200
  59. package/src/viewer/scene/mesh/shadow/ShadowRenderer.js +0 -214
  60. package/src/viewer/scene/model/RENDER_PASSES.js +0 -34
  61. package/src/viewer/scene/model/dtx/BindableDataTexture.js +0 -31
  62. package/src/viewer/scene/model/dtx/lines/DTXLinesBuffer.js +0 -27
  63. package/src/viewer/scene/model/dtx/lines/DTXLinesLayer.js +0 -897
  64. package/src/viewer/scene/model/dtx/lines/DTXLinesState.js +0 -46
  65. package/src/viewer/scene/model/dtx/lines/DTXLinesTextureFactory.js +0 -411
  66. package/src/viewer/scene/model/dtx/lines/dataTextureRamStats.js +0 -49
  67. package/src/viewer/scene/model/dtx/lines/rebucketPositions.js +0 -208
  68. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesColorRenderer.js +0 -389
  69. package/src/viewer/scene/model/dtx/lines/renderers/DTXLinesRenderers.js +0 -65
  70. package/src/viewer/scene/model/dtx/triangles/DTXTrianglesLayer.js +0 -1399
  71. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesBuffer.js +0 -46
  72. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesState.js +0 -250
  73. package/src/viewer/scene/model/dtx/triangles/lib/DTXTrianglesTextureFactory.js +0 -518
  74. package/src/viewer/scene/model/dtx/triangles/lib/dataTextureRamStats.js +0 -54
  75. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesColorRenderer.js +0 -639
  76. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesDepthRenderer.js +0 -464
  77. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesColorRenderer.js +0 -423
  78. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesEdgesRenderer.js +0 -431
  79. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesNormalsRenderer.js +0 -345
  80. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesOcclusionRenderer.js +0 -436
  81. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickDepthRenderer.js +0 -466
  82. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickMeshRenderer.js +0 -437
  83. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsFlatRenderer.js +0 -460
  84. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesPickNormalsRenderer.js +0 -437
  85. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesRenderers.js +0 -307
  86. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSilhouetteRenderer.js +0 -472
  87. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapInitRenderer.js +0 -474
  88. package/src/viewer/scene/model/dtx/triangles/renderers/DTXTrianglesSnapRenderer.js +0 -435
  89. package/src/viewer/scene/model/vbo/ScratchMemory.js +0 -63
  90. package/src/viewer/scene/model/vbo/VBORenderer.js +0 -664
  91. package/src/viewer/scene/model/vbo/batching/lines/VBOBatchingLinesLayer.js +0 -704
  92. package/src/viewer/scene/model/vbo/batching/lines/lib/VBOBatchingLinesBuffer.js +0 -19
  93. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLineSnapInitRenderer.js +0 -318
  94. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesColorRenderer.js +0 -114
  95. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesRenderers.js +0 -99
  96. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSilhouetteRenderer.js +0 -124
  97. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapInitRenderer.js +0 -313
  98. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOBatchingLinesSnapRenderer.js +0 -311
  99. package/src/viewer/scene/model/vbo/batching/lines/renderers/VBOSceneModelLineBatchingRenderer.js +0 -24
  100. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsLayer.js +0 -688
  101. package/src/viewer/scene/model/vbo/batching/points/VBOBatchingPointsRenderer.js +0 -24
  102. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsColorRenderer.js +0 -168
  103. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsOcclusionRenderer.js +0 -136
  104. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickDepthRenderer.js +0 -156
  105. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsPickMeshRenderer.js +0 -148
  106. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsRenderers.js +0 -144
  107. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsShadowRenderer.js +0 -107
  108. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSilhouetteRenderer.js +0 -146
  109. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapInitRenderer.js +0 -315
  110. package/src/viewer/scene/model/vbo/batching/points/renderers/VBOBatchingPointsSnapRenderer.js +0 -305
  111. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesBuffer.js +0 -24
  112. package/src/viewer/scene/model/vbo/batching/triangles/VBOBatchingTrianglesLayer.js +0 -1346
  113. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesColorRenderer.js +0 -131
  114. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesEmphasisRenderer.js +0 -135
  115. package/src/viewer/scene/model/vbo/batching/triangles/renderers/EdgesRenderer.js +0 -12
  116. package/src/viewer/scene/model/vbo/batching/triangles/renderers/Renderers.js +0 -403
  117. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesBatchingRenderer.js +0 -35
  118. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorRenderer.js +0 -252
  119. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesColorTextureRenderer.js +0 -294
  120. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesDepthRenderer.js +0 -115
  121. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesFlatColorRenderer.js +0 -246
  122. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesNormalsRenderer.js +0 -139
  123. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesOcclusionRenderer.js +0 -125
  124. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPBRRenderer.js +0 -561
  125. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickDepthRenderer.js +0 -144
  126. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickMeshRenderer.js +0 -130
  127. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -121
  128. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -131
  129. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesShadowRenderer.js +0 -107
  130. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -144
  131. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapInitRenderer.js +0 -313
  132. package/src/viewer/scene/model/vbo/batching/triangles/renderers/TrianglesSnapRenderer.js +0 -312
  133. package/src/viewer/scene/model/vbo/float16.js +0 -760
  134. package/src/viewer/scene/model/vbo/instancing/lines/VBOInstancingLinesLayer.js +0 -711
  135. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesColorRenderer.js +0 -148
  136. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderer.js +0 -26
  137. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesRenderers.js +0 -139
  138. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSilhouetteRenderer.js +0 -127
  139. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapInitRenderer.js +0 -308
  140. package/src/viewer/scene/model/vbo/instancing/lines/renderers/VBOInstancingLinesSnapRenderer.js +0 -299
  141. package/src/viewer/scene/model/vbo/instancing/points/VBOInstancingPointsLayer.js +0 -733
  142. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsColorRenderer.js +0 -174
  143. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsDepthRenderer.js +0 -156
  144. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsOcclusionRenderer.js +0 -149
  145. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickDepthRenderer.js +0 -170
  146. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsPickMeshRenderer.js +0 -152
  147. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderer.js +0 -26
  148. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsRenderers.js +0 -174
  149. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsShadowRenderer.js +0 -119
  150. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSilhouetteRenderer.js +0 -154
  151. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapInitRenderer.js +0 -307
  152. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingPointsSnapRenderer.js +0 -293
  153. package/src/viewer/scene/model/vbo/instancing/points/renderers/VBOInstancingTrianglesRenderer.js +0 -150
  154. package/src/viewer/scene/model/vbo/instancing/triangles/VBOInstancingTrianglesLayer.js +0 -1289
  155. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesColorRenderer.js +0 -135
  156. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesEmphasisRenderer.js +0 -137
  157. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/EdgesRenderer.js +0 -12
  158. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/Renderers.js +0 -403
  159. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorRenderer.js +0 -267
  160. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesColorTextureRenderer.js +0 -299
  161. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesDepthRenderer.js +0 -126
  162. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatColorRenderer.js +0 -255
  163. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesFlatNormalsRenderer.js +0 -130
  164. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesInstancingRenderer.js +0 -32
  165. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesNormalsRenderer.js +0 -138
  166. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesOcclusionRenderer.js +0 -128
  167. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPBRRenderer.js +0 -561
  168. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickDepthRenderer.js +0 -149
  169. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickMeshRenderer.js +0 -136
  170. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsFlatRenderer.js +0 -130
  171. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesPickNormalsRenderer.js +0 -145
  172. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesShadowRenderer.js +0 -113
  173. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSilhouetteRenderer.js +0 -148
  174. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapInitRenderer.js +0 -319
  175. package/src/viewer/scene/model/vbo/instancing/triangles/renderers/TrianglesSnapRenderer.js +0 -310
  176. package/src/viewer/scene/webgl/Attribute.js +0 -23
  177. package/src/viewer/scene/webgl/Program.js +0 -181
  178. package/src/viewer/scene/webgl/RenderBufferManager.js +0 -34
  179. package/src/viewer/scene/webgl/Sampler.js +0 -18
  180. package/src/viewer/scene/webgl/Shader.js +0 -49
  181. package/src/viewer/scene/webgl/sao/SAODepthLimitedBlurRenderer.js +0 -324
  182. 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,115 +2990,45 @@ 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 ? this._createHashStringFromMatrix(posDecode) : "-";
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;
3011
+
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;
3026
+ }
3027
+ return this._vboLayers[layerId];
3315
3028
  }
3316
3029
 
3317
3030
  _createHashStringFromMatrix(matrix) {
3318
- const matrixString = matrix.join('');
3031
+ const matrixString = matrix.join(";");
3319
3032
  let hash = 0;
3320
3033
  for (let i = 0; i < matrixString.length; i++) {
3321
3034
  const char = matrixString.charCodeAt(i);
@@ -3326,87 +3039,6 @@ export class SceneModel extends Component {
3326
3039
  return hashString;
3327
3040
  }
3328
3041
 
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
- // }
3403
- }
3404
- this._vboInstancingLayers[layerId] = vboInstancingLayer;
3405
- this.layerList.push(vboInstancingLayer);
3406
- this._layersToFinalize.push(vboInstancingLayer);
3407
- return vboInstancingLayer;
3408
- }
3409
-
3410
3042
  /**
3411
3043
  * Creates a {@link SceneModelEntity} within this SceneModel.
3412
3044
  *
@@ -3444,41 +3076,22 @@ export class SceneModel extends Component {
3444
3076
  }
3445
3077
  if (cfg.meshIds === undefined) {
3446
3078
  this.error("Config missing: meshIds");
3447
- return;
3079
+ return null;
3448
3080
  }
3081
+
3082
+ const notFalse = v => v !== false;
3449
3083
  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
- }
3084
+ flags |= (this._visible && notFalse(cfg.visible) && ENTITY_FLAGS.VISIBLE);
3085
+ flags |= (this._pickable && notFalse(cfg.pickable) && ENTITY_FLAGS.PICKABLE);
3086
+ flags |= (this._culled && notFalse(cfg.culled) && ENTITY_FLAGS.CULLED);
3087
+ flags |= (this._clippable && notFalse(cfg.clippable) && ENTITY_FLAGS.CLIPPABLE);
3088
+ flags |= (this._collidable && notFalse(cfg.collidable) && ENTITY_FLAGS.COLLIDABLE);
3089
+ flags |= (this._xrayed && notFalse(cfg.xrayed) && ENTITY_FLAGS.XRAYED);
3090
+ flags |= (this._highlighted && notFalse(cfg.highlighted) && ENTITY_FLAGS.HIGHLIGHTED);
3091
+ flags |= (this._selected && notFalse(cfg.selected) && ENTITY_FLAGS.SELECTED);
3092
+ flags |= (this._edges && notFalse(cfg.edges) && ENTITY_FLAGS.EDGES);
3477
3093
  cfg.flags = flags;
3478
- return this._createEntity(cfg);
3479
- }
3480
3094
 
3481
- _createEntity(cfg) {
3482
3095
  let meshes = [];
3483
3096
  for (let i = 0, len = cfg.meshIds.length; i < len; i++) {
3484
3097
  const meshId = cfg.meshIds[i];
@@ -3526,8 +3139,7 @@ export class SceneModel extends Component {
3526
3139
  const layer = this._layersToFinalize[i];
3527
3140
  layer.finalize();
3528
3141
  }
3529
- this._vboBatchingLayers = {};
3530
- this._vboInstancingLayers = {};
3142
+ this._vboLayers = {};
3531
3143
  this._dtxLayers = {};
3532
3144
  this._layersToFinalize = [];
3533
3145
  for (let i = 0, len = this._entitiesToFinalize.length; i < len; i++) {
@@ -3721,263 +3333,48 @@ export class SceneModel extends Component {
3721
3333
 
3722
3334
  // -------------- RENDERING ---------------------------------------------------------------------------------------
3723
3335
 
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
3336
 
3832
3337
  /**
3833
3338
  * @private
3834
3339
  */
3835
- drawOcclusion(frameCtx) {
3836
- if (this.numVisibleLayerPortions === 0) {
3340
+ _withEachVisibleLayer(testNumVisibleLayerPortions, cb) {
3341
+ if (testNumVisibleLayerPortions && (this.numVisibleLayerPortions === 0)) {
3837
3342
  return;
3838
3343
  }
3839
3344
  const renderFlags = this.renderFlags;
3840
3345
  for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3841
3346
  const layerIndex = renderFlags.visibleLayers[i];
3842
- this.layerList[layerIndex].drawOcclusion(renderFlags, frameCtx);
3347
+ cb(this.layerList[layerIndex]);
3843
3348
  }
3844
3349
  }
3845
3350
 
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
- }
3351
+ drawColorOpaque (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawColorOpaque (this.renderFlags, frameCtx)); }
3352
+ drawColorTransparent (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawColorTransparent (this.renderFlags, frameCtx)); }
3353
+ drawDepth (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawDepth (this.renderFlags, frameCtx)); } // Dedicated to SAO because it skips transparent objects
3354
+ drawSilhouetteXRayed (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawSilhouetteXRayed (this.renderFlags, frameCtx)); }
3355
+ drawSilhouetteHighlighted(frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawSilhouetteHighlighted(this.renderFlags, frameCtx)); }
3356
+ drawSilhouetteSelected (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawSilhouetteSelected (this.renderFlags, frameCtx)); }
3357
+ drawEdgesColorOpaque (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesColorOpaque (this.renderFlags, frameCtx)); }
3358
+ drawEdgesColorTransparent(frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesColorTransparent(this.renderFlags, frameCtx)); }
3359
+ drawEdgesXRayed (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesXRayed (this.renderFlags, frameCtx)); }
3360
+ drawEdgesHighlighted (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesHighlighted (this.renderFlags, frameCtx)); }
3361
+ drawEdgesSelected (frameCtx) { this._withEachVisibleLayer(false, layer => layer.drawEdgesSelected (this.renderFlags, frameCtx)); }
3362
+ drawOcclusion (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawOcclusion (this.renderFlags, frameCtx)); }
3363
+ drawShadow (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawShadow (this.renderFlags, frameCtx)); }
3364
+ drawPickMesh (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawPickMesh (this.renderFlags, frameCtx)); }
3365
+ drawPickDepths (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawPickDepths (this.renderFlags, frameCtx)); }
3366
+ drawPickNormals (frameCtx) { this._withEachVisibleLayer(true, layer => layer.drawPickNormals (this.renderFlags, frameCtx)); }
3367
+ _drawSnap (frameCtx, isSnapInit) { this._withEachVisibleLayer(true, layer => layer.drawSnap (this.renderFlags, frameCtx, isSnapInit)); }
3859
3368
 
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
-
3902
- /**
3903
- * Called by SceneModelMesh.drawPickNormals()
3904
- * @private
3905
- */
3906
- drawPickNormals(frameCtx) {
3907
- if (this.numVisibleLayerPortions === 0) {
3908
- return;
3909
- }
3910
- const renderFlags = this.renderFlags;
3911
- for (let i = 0, len = renderFlags.visibleLayers.length; i < len; i++) {
3912
- const layerIndex = renderFlags.visibleLayers[i];
3913
- this.layerList[layerIndex].drawPickNormals(renderFlags, frameCtx);
3914
- }
3915
- }
3916
-
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
- }
3940
-
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
- }
3369
+ drawSnapInit(frameCtx) { this._drawSnap(frameCtx, true ); }
3370
+ drawSnap (frameCtx) { this._drawSnap(frameCtx, false); }
3964
3371
 
3965
3372
  /**
3966
3373
  * Destroys this SceneModel.
3967
3374
  */
3968
3375
  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 = {};
3376
+ Object.values(this._vboLayers).forEach(l => l.destroy());
3377
+ this._vboLayers = {};
3981
3378
  this.scene.camera.off(this._onCameraViewMatrix);
3982
3379
  this.scene.off(this._onTick);
3983
3380
  for (let i = 0, len = this.layerList.length; i < len; i++) {
@@ -3987,7 +3384,7 @@ export class SceneModel extends Component {
3987
3384
  for (let i = 0, len = this._entityList.length; i < len; i++) {
3988
3385
  this._entityList[i]._destroy();
3989
3386
  }
3990
- this._layersToFinalize = {};
3387
+ this._layersToFinalize = [];
3991
3388
  // Object.entries(this._geometries).forEach(([id, geometry]) => {
3992
3389
  // geometry.destroy();
3993
3390
  // });
@@ -4001,7 +3398,6 @@ export class SceneModel extends Component {
4001
3398
  if (this._isModel) {
4002
3399
  this.scene._deregisterModel(this);
4003
3400
  }
4004
- putScratchMemory();
4005
3401
  super.destroy();
4006
3402
  }
4007
3403
  }