@babylonjs/core 9.3.1 → 9.3.3

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 (84) hide show
  1. package/Engines/AbstractEngine/abstractEngine.textureSelector.d.ts +45 -0
  2. package/Engines/AbstractEngine/abstractEngine.textureSelector.js +69 -0
  3. package/Engines/AbstractEngine/abstractEngine.textureSelector.js.map +1 -0
  4. package/Engines/AbstractEngine/index.d.ts +2 -0
  5. package/Engines/AbstractEngine/index.js +4 -0
  6. package/Engines/AbstractEngine/index.js.map +1 -1
  7. package/Engines/Extensions/engine.textureSelector.d.ts +2 -45
  8. package/Engines/Extensions/engine.textureSelector.js +8 -68
  9. package/Engines/Extensions/engine.textureSelector.js.map +1 -1
  10. package/Engines/abstractEngine.js +2 -2
  11. package/Engines/abstractEngine.js.map +1 -1
  12. package/FlowGraph/flowGraph.d.ts +22 -0
  13. package/FlowGraph/flowGraph.js +11 -0
  14. package/FlowGraph/flowGraph.js.map +1 -1
  15. package/FlowGraph/flowGraphCoordinator.d.ts +2 -1
  16. package/FlowGraph/flowGraphCoordinator.js +4 -2
  17. package/FlowGraph/flowGraphCoordinator.js.map +1 -1
  18. package/FlowGraph/flowGraphParser.js +7 -0
  19. package/FlowGraph/flowGraphParser.js.map +1 -1
  20. package/FlowGraph/typeDefinitions.d.ts +8 -0
  21. package/FlowGraph/typeDefinitions.js.map +1 -1
  22. package/Lights/Clustered/clusteredLightContainer.d.ts +1 -0
  23. package/Lights/Clustered/clusteredLightContainer.js +19 -0
  24. package/Lights/Clustered/clusteredLightContainer.js.map +1 -1
  25. package/Lights/light.d.ts +6 -0
  26. package/Lights/light.js +8 -0
  27. package/Lights/light.js.map +1 -1
  28. package/Lights/spotLight.d.ts +2 -0
  29. package/Lights/spotLight.js +10 -0
  30. package/Lights/spotLight.js.map +1 -1
  31. package/Materials/Background/backgroundMaterial.js +4 -1
  32. package/Materials/Background/backgroundMaterial.js.map +1 -1
  33. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js +6 -2
  34. package/Materials/GaussianSplatting/gaussianSplattingMaterial.js.map +1 -1
  35. package/Materials/Node/Blocks/Dual/lightBlock.d.ts +8 -0
  36. package/Materials/Node/Blocks/Dual/lightBlock.js +16 -0
  37. package/Materials/Node/Blocks/Dual/lightBlock.js.map +1 -1
  38. package/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.js +3 -0
  39. package/Materials/Node/Blocks/PBR/pbrMetallicRoughnessBlock.js.map +1 -1
  40. package/Materials/Node/nodeMaterial.js +4 -1
  41. package/Materials/Node/nodeMaterial.js.map +1 -1
  42. package/Materials/PBR/openpbrMaterial.js +4 -1
  43. package/Materials/PBR/openpbrMaterial.js.map +1 -1
  44. package/Materials/PBR/pbrBaseMaterial.js +4 -1
  45. package/Materials/PBR/pbrBaseMaterial.js.map +1 -1
  46. package/Materials/materialHelper.functions.d.ts +12 -0
  47. package/Materials/materialHelper.functions.js +24 -0
  48. package/Materials/materialHelper.functions.js.map +1 -1
  49. package/Materials/standardMaterial.js +4 -1
  50. package/Materials/standardMaterial.js.map +1 -1
  51. package/Meshes/GaussianSplatting/gaussianSplattingMesh.d.ts +13 -0
  52. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js +26 -0
  53. package/Meshes/GaussianSplatting/gaussianSplattingMesh.js.map +1 -1
  54. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.d.ts +3 -0
  55. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js +113 -10
  56. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.js.map +1 -1
  57. package/Misc/tools.js +1 -1
  58. package/Misc/tools.js.map +1 -1
  59. package/Particles/gpuParticleSystem.d.ts +35 -2
  60. package/Particles/gpuParticleSystem.js +272 -6
  61. package/Particles/gpuParticleSystem.js.map +1 -1
  62. package/Particles/thinParticleSystem.js +5 -0
  63. package/Particles/thinParticleSystem.js.map +1 -1
  64. package/Rendering/depthRenderer.d.ts +8 -0
  65. package/Rendering/depthRenderer.js +48 -13
  66. package/Rendering/depthRenderer.js.map +1 -1
  67. package/Rendering/depthRendererSceneComponent.d.ts +1 -0
  68. package/Rendering/depthRendererSceneComponent.js +26 -0
  69. package/Rendering/depthRendererSceneComponent.js.map +1 -1
  70. package/Shaders/gpuRenderParticles.vertex.js +7 -0
  71. package/Shaders/gpuRenderParticles.vertex.js.map +1 -1
  72. package/XR/features/WebXRBodyTracking.d.ts +952 -0
  73. package/XR/features/WebXRBodyTracking.js +2221 -0
  74. package/XR/features/WebXRBodyTracking.js.map +1 -0
  75. package/XR/features/index.d.ts +1 -0
  76. package/XR/features/index.js +1 -0
  77. package/XR/features/index.js.map +1 -1
  78. package/XR/webXRFeaturesManager.d.ts +7 -0
  79. package/XR/webXRFeaturesManager.js +4 -0
  80. package/XR/webXRFeaturesManager.js.map +1 -1
  81. package/package.json +1 -1
  82. package/sceneComponent.d.ts +1 -0
  83. package/sceneComponent.js +1 -0
  84. package/sceneComponent.js.map +1 -1
@@ -57,6 +57,19 @@ export declare class GaussianSplattingMesh extends GaussianSplattingMeshBase {
57
57
  * @returns "GaussianSplattingMesh"
58
58
  */
59
59
  getClassName(): string;
60
+ /**
61
+ * Is this node ready to be used/rendered.
62
+ * Force-syncs every part proxy's world matrix into `_partMatrices` BEFORE delegating to
63
+ * the base readiness check. This guarantees that any pending proxy transform changes
64
+ * (for example a user-set `proxy.position`) are reflected in the next sort post, so the
65
+ * base `isReady` will only return true once `sortAppliedId === sortRequestId` for that
66
+ * up-to-date state. Without this, the proxy's `onAfterWorldMatrixUpdateObservable` would
67
+ * fire during the first render and queue a fresh sort AFTER readiness was reported,
68
+ * leaving the rendered frame with stale splat order on `renderCount=1` runs.
69
+ * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
70
+ * @returns true when ready
71
+ */
72
+ isReady(completeCheck?: boolean): boolean;
60
73
  /**
61
74
  * Disposes proxy meshes and clears part data in addition to the base class GPU resources.
62
75
  * @param doNotRecurse Set to true to not recurse into each children
@@ -103,6 +103,26 @@ export class GaussianSplattingMesh extends GaussianSplattingMeshBase {
103
103
  getClassName() {
104
104
  return "GaussianSplattingMesh";
105
105
  }
106
+ /**
107
+ * Is this node ready to be used/rendered.
108
+ * Force-syncs every part proxy's world matrix into `_partMatrices` BEFORE delegating to
109
+ * the base readiness check. This guarantees that any pending proxy transform changes
110
+ * (for example a user-set `proxy.position`) are reflected in the next sort post, so the
111
+ * base `isReady` will only return true once `sortAppliedId === sortRequestId` for that
112
+ * up-to-date state. Without this, the proxy's `onAfterWorldMatrixUpdateObservable` would
113
+ * fire during the first render and queue a fresh sort AFTER readiness was reported,
114
+ * leaving the rendered frame with stale splat order on `renderCount=1` runs.
115
+ * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
116
+ * @returns true when ready
117
+ */
118
+ isReady(completeCheck = false) {
119
+ for (const proxy of this._partProxies) {
120
+ if (proxy) {
121
+ proxy.computeWorldMatrix(true);
122
+ }
123
+ }
124
+ return super.isReady(completeCheck);
125
+ }
106
126
  /**
107
127
  * Disposes proxy meshes and clears part data in addition to the base class GPU resources.
108
128
  * @param doNotRecurse Set to true to not recurse into each children
@@ -239,6 +259,12 @@ export class GaussianSplattingMesh extends GaussianSplattingMeshBase {
239
259
  this._partVisibility.push(1.0);
240
260
  }
241
261
  }
262
+ // Skip the post / sort if the matrix is unchanged. Babylon recomputes the proxy mesh's world matrix every frame
263
+ // and fires onAfterWorldMatrixUpdateObservable, so without this guard a stable scene would queue a forced sort
264
+ // every frame and `isReady()` would never settle (sortRequestId would keep advancing past sortAppliedId).
265
+ if (this._partMatrices[partIndex].equals(worldMatrix)) {
266
+ return;
267
+ }
242
268
  this._partMatrices[partIndex].copyFrom(worldMatrix);
243
269
  // During a batch rebuild suppress intermediate posts — the final correct set is posted
244
270
  // once the full rebuild completes (at the end of removePart).
@@ -1 +1 @@
1
- {"version":3,"file":"gaussianSplattingMesh.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.ts"],"names":[],"mappings":"AAEA,OAAO,EAA6B,UAAU,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAGxF,OAAO,EAAE,gCAAgC,EAAE,MAAM,4DAA4D,CAAC;AAC9G,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,8BAA8B,CAAC;AACtC,OAAO,EAAE,8BAA8B,EAAE,MAAM,kCAAkC,CAAC;AAIlF,MAAM,+BAA+B,GAAG,EAAE,CAAC;AAC3C,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAc7C;;;;;;;GAOG;AACH,SAAS,mBAAmB,CAAC,WAAuB;IAChD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC;IAClC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,MAAM,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,CAAC,GAAG,KAAK,GAAG,MAAM,IAAI,WAAW,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;YAC5D,KAAK,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC,IAAI,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,UAAkC;IACxD,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,UAAU,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;IAC/C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAChC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC;IACpB,CAAC;IAED,OAAO,WAAW,CAAC;AACvB,CAAC;AAED;;;;;GAKG;AACH,MAAM,OAAO,qBAAsB,SAAQ,yBAAyB;IAsBhE,gEAAgE;IAChE,IAAW,kBAAkB;QACzB,OAAO,IAAI,CAAC,mBAAmB,CAAC;IACpC,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,IAAY,EAAE,MAAwB,IAAI,EAAE,QAAyB,IAAI,EAAE,YAAqB,KAAK,EAAE,6BAAsC,KAAK;QAC1J,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAnCvC;;WAEG;QACK,iBAAY,GAAqC,EAAE,CAAC;QAE5D;;WAEG;QACO,kBAAa,GAAa,EAAE,CAAC;QAEvC,iGAAiG;QACzF,gBAAW,GAAY,KAAK,CAAC;QAErC;;WAEG;QACO,oBAAe,GAAa,EAAE,CAAC;QAEjC,wBAAmB,GAA0B,IAAI,CAAC;QAClD,iBAAY,GAAyB,IAAI,CAAC;QAiB9C,uFAAuF;QACvF,mFAAmF;QACnF,6CAA6C;QAC7C,IAAI,CAAC,uBAAuB,GAAG,IAAI,CAAC;QACpC,IAAI,CAAC,2BAA2B,GAAG,0BAA0B,CAAC;IAClE,CAAC;IAED;;;OAGG;IACa,YAAY;QACxB,OAAO,uBAAuB,CAAC;IACnC,CAAC;IAED;;;OAGG;IACa,OAAO,CAAC,YAAsB;QAC1C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpC,KAAK,CAAC,OAAO,EAAE,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,mBAAmB,EAAE,OAAO,EAAE,CAAC;QACpC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAChC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAChC,CAAC;IAED,8EAA8E;IAC9E,4BAA4B;IAC5B,8EAA8E;IAE9E;;;;;OAKG;IACgB,gBAAgB,CAAC,MAAc;QAC9C,MAAM,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACrG,MAAM,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACtG,CAAC;IAED;;;;;OAKG;IACgB,oBAAoB,CAAC,WAAuB,EAAE,aAAqB;QAClF,IAAI,CAAC,YAAY,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACH,IAAoB,UAAU;QAC1B,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACgB,kBAAkB;QACjC,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,+EAA+E;YAC/E,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAChD,OAAO;QACX,CAAC;QACD,KAAK,CAAC,kBAAkB,EAAE,CAAC;IAC/B,CAAC;IAED;;;;OAIG;IACgB,yBAAyB,CAAC,WAAoB;QAC7D,IAAI,CAAC,yBAAyB,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC,CAAC;IAChF,CAAC;IAED;;;OAGG;IACgB,oBAAoB;QACnC,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACa,uBAAuB,CAAC,MAAc;QAClD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC5B,OAAO;QACX,CAAC;QACD,MAAM,CAAC,UAAU,CAAC,oBAAoB,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClE,MAAM,aAAa,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;QAC5D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,CAAC,WAAW,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAC/C,MAAM,kBAAkB,GAAa,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,CAAC;IAED,8EAA8E;IAC9E,sCAAsC;IACtC,8EAA8E;IAE9E;;OAEG;IACH,IAAW,SAAS;QAChB,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,IAAW,cAAc;QACrB,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;IAED;;;;;;OAMG;IACI,qBAAqB,CAAC,SAAiB,EAAE,WAAmB;QAC/D,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;YAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,aAAa,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;gBAC5C,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC/C,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QACD,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QACpD,uFAAuF;QACvF,8DAA8D;QAC9D,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACpB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC/G,CAAC;YACD,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,qBAAqB,CAAC,SAAiB;QAC1C,OAAO,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;IAClE,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,SAAiB;QACtC,OAAO,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACI,iBAAiB,CAAC,SAAiB,EAAE,KAAa;QACrD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;IAC1E,CAAC;IAEkB,aAAa,CAAC,MAAiC;QAC9D,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC5B,IAAI,CAAC,mBAAmB,GAAI,MAAgC,CAAC,mBAAmB,EAAE,KAAK,EAAG,CAAC;IAC/F,CAAC;IAEkB,iBAAiB,CAAC,WAAoB;QACrD,MAAM,uBAAuB,GAAG,CAAC,IAAgB,EAAE,KAAa,EAAE,MAAc,EAAE,MAAc,EAAE,EAAE;YAChG,OAAO,IAAI,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,CAAC,6BAA6B,EAAE,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAChK,CAAC,CAAC;QAEF,yFAAyF;QACzF,+FAA+F;QAC/F,2FAA2F;QAC3F,sFAAsF;QACtF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjD,IAAI,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC5B,IAAI,CAAC,mBAAmB,GAAG,uBAAuB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;gBACtH,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;gBACrE,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACJ,MAAM,YAAY,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;gBACxD,IAAI,YAAY,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,IAAI,YAAY,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,EAAE,CAAC;oBAChF,6DAA6D;oBAC7D,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;oBACnC,IAAI,CAAC,mBAAmB,GAAG,uBAAuB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAC;oBACtH,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;oBACrE,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;gBACzE,CAAC;qBAAM,CAAC;oBACJ,oFAAoF;oBACpF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;gBACnG,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAEkB,kBAAkB,CACjC,cAA4B,EAC5B,IAAiB,EACjB,IAAiB,EACjB,UAAsB,EACtB,SAAiB,EACjB,SAAiB,EACjB,EAAiB,EACjB,WAAwB;QAExB,KAAK,CAAC,kBAAkB,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAC3F,IAAI,WAAW,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1C,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;YAC7C,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC;YAC7C,MAAM,eAAe,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;YACnF,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,mBAAmB,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YAE5G,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,kBAAkB;IAClB,8EAA8E;IAE9E;;;;;OAKG;IACO,yBAAyB,CAAC,WAAoB,EAAE,WAAmC;QACzF,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3C,OAAO;QACX,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,YAAa,CAAC,CAAC;QAClD,IAAI,CAAC,mBAAmB,GAAG,IAAI,UAAU,CACrC,MAAM,EACN,WAAW,CAAC,CAAC,EACb,WAAW,CAAC,CAAC,EACb,SAAS,CAAC,iBAAiB,EAC3B,IAAI,CAAC,MAAM,EACX,KAAK,EACL,KAAK,EACL,SAAS,CAAC,6BAA6B,EACvC,SAAS,CAAC,yBAAyB,CACtC,CAAC;QACF,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACrE,IAAI,CAAC,mBAAmB,CAAC,KAAK,GAAG,SAAS,CAAC,yBAAyB,CAAC;QACrE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,WAAW,EAAE,WAAW,IAAI,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;IACL,CAAC;IAEO,yBAAyB,CAC7B,MAAoC,EACpC,SAAiB,EACjB,IAAiB,EACjB,IAAiB,EACjB,UAAsB,EACtB,EAA4B,EAC5B,OAAgB,EAChB,OAAgB;QAEhB,IAAI,CAAC,qBAAqB,CAAC,MAA8C,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxI,CAAC;IAEO,yBAAyB,CAAC,KAAqC;QACnE,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC7D,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,GAAG,+BAA+B,CAAC;QAClF,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,GAAG,+BAA+B,CAAC;QAC7E,MAAM,YAAY,GAAG,KAAK,CAAC,aAAa,GAAG,iCAAiC,CAAC;QAC7E,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,GAAG,iCAAiC,CAAC;QAE5E,OAAO;YACH,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,eAAe,EAAE,eAAe,GAAG,eAAe,CAAC;YACvF,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,YAAY,GAAG,YAAY,CAAC,CAAC,IAAI,IAAI;YACzG,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;YACpC,UAAU,EAAE,KAAK;YACjB,cAAc,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,cAAc,EAAE;YAC5C,eAAe,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,eAAe,EAAE;YAC9C,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;SACpB,CAAC;IACN,CAAC;IAEO,qBAAqB,CAAC,mBAA2B,EAAE,UAAkB,EAAE,MAAsC,EAAE,QAAgB;QACnI,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;YACpD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,OAAO;QACX,CAAC;QAED,MAAM,eAAe,GAAG,CAAC,IAAiB,EAAe,EAAE;YACvD,OAAO,IAAI,YAAY,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAG,IAAmC,CAAC,MAAsB,CAAC;QAC7G,CAAC,CAAC;QAEF,MAAM,gBAAgB,GAAG,IAAI,UAAU,CAAC,UAAU,GAAG,+BAA+B,CAAC,CAAC;QACtF,IAAI,eAAe,GAAG,CAAC,CAAC;QAExB,IAAI,IAAI,CAAC,WAAW,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;YAC9C,gBAAgB,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,mBAAmB,GAAG,+BAA+B,CAAC,EAAE,eAAe,CAAC,CAAC;YACnJ,eAAe,IAAI,mBAAmB,GAAG,+BAA+B,CAAC;QAC7E,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACrB,SAAS;YACb,CAAC;YAED,MAAM,eAAe,GAAG,KAAK,CAAC,YAAY,GAAG,+BAA+B,CAAC;YAC7E,gBAAgB,CAAC,GAAG,CAAC,IAAI,UAAU,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,EAAE,eAAe,CAAC,CAAC;YAC9G,eAAe,IAAI,eAAe,CAAC;QACvC,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC;QAE3C,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACpB,OAAO;QACX,CAAC;QAED,MAAM,YAAY,GAAiB,EAAE,CAAC;QACtC,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,QAAQ,EAAE,YAAY,EAAE,EAAE,CAAC;YACjE,YAAY,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,GAAG,iCAAiC,CAAC,CAAC,CAAC;QACtF,CAAC;QAED,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO,IAAI,mBAAmB,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,oBAAoB,GAAG,mBAAmB,GAAG,iCAAiC,CAAC;YACrF,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC;gBAC5E,IAAI,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oBACrC,YAAY,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,oBAAoB,CAAC,EAAE,YAAY,CAAC,CAAC;gBAC/G,CAAC;YACL,CAAC;YACD,YAAY,IAAI,oBAAoB,CAAC;QACzC,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,MAAM,iBAAiB,GAAG,KAAK,CAAC,YAAY,GAAG,iCAAiC,CAAC;YACjF,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAChB,KAAK,IAAI,YAAY,GAAG,CAAC,EAAE,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,CAAC;oBAC5E,IAAI,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wBACtC,YAAY,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,YAAY,CAAC,CAAC;oBAC7G,CAAC;gBACL,CAAC;YACL,CAAC;YACD,YAAY,IAAI,iBAAiB,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,YAAY,CAAC;IAChC,CAAC;IAED;;;;;;;;OAQG;IACO,iBAAiB,CAAC,MAAsC,EAAE,aAAsB;QACtF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC;QACxD,CAAC;QAED,WAAW;QACX,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,qEAAqE,CAAC,CAAC;YAC3F,CAAC;YACD,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACnB,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;YAC7F,CAAC;QACL,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;QACvE,MAAM,UAAU,GAAG,WAAW,GAAG,eAAe,CAAC;QAEjD,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QACrD,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;QACpD,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtD,uDAAuD;QACvD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAChD,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,aAAa,GAAG,aAAa,CAAC,CAAC;QAC5D,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QAErD,6BAA6B;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC;QAC/E,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,IAAI,EAAE,GAA6B,SAAS,CAAC;QAC7C,IAAI,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,aAAa,GAAG,EAAE,CAAC;YACzB,EAAE,GAAG,EAAE,CAAC;YACR,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;gBACnC,EAAE,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,aAAa,GAAG,aAAa,CAAC,CAAC,CAAC;YAC3D,CAAC;QACL,CAAC;QAED,2EAA2E;QAC3E,MAAM,WAAW,GAAG,IAAI,CAAC,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACtE,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE/E,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAmB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;QACnI,MAAM,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAmB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAEtI,yDAAyD;QACzD,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC;QAC1C,IAAI,CAAC,eAAe,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC;QAC3D,IAAI,WAAW,IAAI,YAAY,EAAE,CAAC;YAC9B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC;QAED,6BAA6B;QAC7B,IAAI,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC;QACnC,IAAI,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACrC,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,6DAA6D;YAC7D,YAAY,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;YAC3C,aAAa,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,UAAU,CAAC,aAAa,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;QAE7D,MAAM,mBAAmB,GAAa,EAAE,CAAC;QACzC,MAAM,yBAAyB,GAAa,EAAE,CAAC;QAC/C,IAAI,SAAS,GAAG,WAAW,CAAC;QAC5B,MAAM,YAAY,GAAG,gCAAgC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAC/E,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,aAAa,IAAI,YAAY,EAAE,CAAC;gBAChC,MAAM,IAAI,KAAK,CAAC,+CAA+C,YAAY,oBAAoB,CAAC,CAAC;YACrG,CAAC;YACD,MAAM,YAAY,GAAG,aAAa,EAAE,CAAC;YACrC,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvC,yBAAyB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,GAAG,KAAK,CAAC,YAAY,CAAC,CAAC;YAChF,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC;QACpC,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,4EAA4E;YAC5E,4EAA4E;YAC5E,8EAA8E;YAC9E,6EAA6E;YAC7E,6EAA6E;YAC7E,iEAAiE;YACjE,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;gBAClB,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,6EAA6E;oBAC7E,EAAE;oBACF,yFAAyF;oBACzF,yFAAyF;oBACzF,oFAAoF;oBACpF,uCAAuC;oBACvC,EAAE;oBACF,wCAAwC;oBACxC,kFAAkF;oBAClF,iFAAiF;oBACjF,oFAAoF;oBACpF,6EAA6E;oBAC7E,+EAA+E;oBAC/E,gFAAgF;oBAChF,IAAI,aAAa,GAAG,CAAC,CAAC;oBAEtB,wEAAwE;oBACxE,6DAA6D;oBAC7D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBAC5C,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC7G,MAAM,UAAU,GAAG,WAAW,GAAG,gBAAgB,CAAC;wBAClD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;4BACjB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;4BAC/C,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;4BACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;gCAClC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;4BACtF,CAAC;4BACD,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gCACrB,MAAM,aAAa,GAAG,EAAE,CAAC;gCACzB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;oCAChD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;wCAC/B,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;oCACpF,CAAC;gCACL,CAAC;4BACL,CAAC;4BACD,aAAa,IAAI,UAAU,CAAC;wBAChC,CAAC;oBACL,CAAC;oBAED,wEAAwE;oBACxE,2EAA2E;oBAC3E,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC;wBACxE,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;wBAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;4BACT,SAAS;wBACb,CAAC;wBACD,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;wBACrD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACV,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,IAAI,wDAAwD,CAAC,CAAC;wBACzH,CAAC;wBACD,IAAI,CAAC,yBAAyB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;wBACpG,aAAa,IAAI,MAAM,CAAC,YAAY,CAAC;oBACzC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,4EAA4E;oBAC5E,2EAA2E;oBAC3E,iFAAiF;oBACjF,yEAAyE;oBACzE,sEAAsE;oBACtE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBACnB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC/C,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBACjD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;4BACnC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;wBACtF,CAAC;wBACD,IAAI,EAAE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;4BACrB,MAAM,aAAa,GAAG,EAAE,CAAC;4BACzB,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;gCAChD,IAAI,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;oCAC/B,EAAE,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,WAAW,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;gCACrF,CAAC;4BACL,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,2FAA2F;QAC3F,yFAAyF;QACzF,yFAAyF;QACzF,sCAAsC;QACtC,IAAI,WAAW,EAAE,CAAC;YACd,MAAM,aAAa,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC;YACnD,IAAI,aAAa,GAAG,WAAW,EAAE,CAAC;gBAC9B,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACjC,uEAAuE;oBACvE,yEAAyE;oBACzE,2EAA2E;oBAC3E,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;wBACnB,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC/C,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBACjD,KAAK,IAAI,CAAC,GAAG,aAAa,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC/C,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;wBACzF,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,6EAA6E;oBAC7E,4EAA4E;oBAC5E,EAAE;oBACF,yDAAyD;oBACzD,6EAA6E;oBAC7E,4EAA4E;oBAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACvF,MAAM,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC,CAAC,gCAAgC;oBAC7E,MAAM,QAAQ,GAA0B,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACvF,MAAM,QAAQ,GAA4B,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACzF,MAAM,UAAU,GAAa,IAAI,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACzE,2DAA2D;oBAC3D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;wBAC9D,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBAC/C,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;wBACjD,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBACtB,CAAC;oBACD,qEAAqE;oBACrE,IAAI,SAAS,GAAG,UAAU,CAAC;oBAC3B,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;wBACnD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;wBACpC,IAAI,CAAC,KAAK,EAAE,CAAC;4BACT,SAAS;wBACb,CAAC;wBACD,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;wBACrD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;4BACjC,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,CAAC,IAAI,wDAAwD,CAAC,CAAC;wBACzH,CAAC;wBACD,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;wBAClD,QAAQ,CAAC,EAAE,CAAC,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;wBACpD,UAAU,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC;wBAC3B,SAAS,IAAI,MAAM,CAAC,YAAY,CAAC;oBACrC,CAAC;oBACD,KAAK,IAAI,QAAQ,GAAG,aAAa,EAAE,QAAQ,GAAG,WAAW,EAAE,QAAQ,EAAE,EAAE,CAAC;wBACpE,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACpE,MAAM,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAClE,MAAM,IAAI,GAAG,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;wBAClE,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;4BACf,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClI,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,yBAAyB;QACzB,SAAS,GAAG,WAAW,CAAC;QACxB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/F,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC;QACpC,CAAC;QAED,uCAAuC;QACvC,MAAM,SAAS,GAAG,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC;QAC3C,KAAK,IAAI,CAAC,GAAG,UAAU,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YAC1C,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC;QAED,6CAA6C;QAC7C,IAAI,UAAU,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;YACnC,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QACzE,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC;QAC/B,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC;QAE7B,qHAAqH;QACrH,uHAAuH;QACvH,+FAA+F;QAC/F,uDAAuD;QACvD,mHAAmH;QACnH,kDAAkD;QAClD,MAAM,eAAe,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1C,IAAI,eAAe,EAAE,CAAC;YAClB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;YAC9B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACD,wBAAwB;YACxB,IAAI,WAAW,EAAE,CAAC;gBACd,6EAA6E;gBAC7E,kFAAkF;gBAClF,oEAAoE;gBACpE,IAAI,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;gBACpC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC,GAAG,YAAY,EAAE,EAAE,CAAC,CAAC;YAC1H,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,CAAC,eAAe,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;YAC5E,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACtB,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;YAC1C,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAE5B,8BAA8B;YAC9B,MAAM,WAAW,GAAqC,EAAE,CAAC;YACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACrC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACxB,MAAM,YAAY,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAAC;gBAE5C,MAAM,eAAe,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;gBAC/C,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;gBAE1D,MAAM,SAAS,GAAG,IAAI,8BAA8B,CAChD,KAAK,CAAC,IAAI,EACV,IAAI,CAAC,QAAQ,EAAE,EACf,IAAI,EACJ,YAAY,EACZ,KAAK,CAAC,eAAe,EAAE,EACvB,KAAK,CAAC,YAAY,EAClB,yBAAyB,CAAC,CAAC,CAAC,EAC5B,yBAAyB,CAAC,CAAC,CAAC,CAC/B,CAAC;gBAEF,IAAI,aAAa,EAAE,CAAC;oBAChB,KAAK,CAAC,OAAO,EAAE,CAAC;gBACpB,CAAC;gBAED,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,eAAe,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC7E,SAAS,CAAC,kBAAkB,GAAG,UAAU,CAAC;gBAC1C,SAAS,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAEnC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAC5C,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAChC,CAAC;YAED,mHAAmH;YACnH,6GAA6G;YAC7G,IAAI,eAAe,EAAE,CAAC;gBAClB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;oBACf,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC/G,CAAC;gBACD,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;gBAC7B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;YAED,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAChD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,6EAA6E;YAC7E,IAAI,eAAe,EAAE,CAAC;gBAClB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YACjC,CAAC;YACD,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED,8EAA8E;IAC9E,sBAAsB;IACtB,8EAA8E;IAE9E;;;;;;;OAOG;IACI,OAAO,CAAC,KAA4B,EAAE,eAAwB,IAAI;QACrE,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;QACtE,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC;IAC1B,CAAC;IAED;;;;;;;OAOG;IACI,UAAU,CAAC,KAAa;QAC3B,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACvC,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,wBAAwB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAClF,CAAC;QAED,0FAA0F;QAC1F,MAAM,SAAS,GAA0J,EAAE,CAAC;QAC5K,KAAK,IAAI,UAAU,GAAG,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,CAAC;YAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;YAC5C,IAAI,CAAC,KAAK,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;gBACjC,SAAS;YACb,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC;YACrD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,oFAAoF,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC;YACxH,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;QACzK,CAAC;QACD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAElD,+FAA+F;QAC/F,KAAK,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CAAC,iDAAiD,SAAS,CAAC,IAAI,qBAAqB,CAAC,CAAC;YAC1G,CAAC;YACD,IAAI,MAAM,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC1C,MAAM,IAAI,KAAK,CAAC,6CAA6C,SAAS,CAAC,IAAI,qBAAqB,CAAC,CAAC;YACtG,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,wFAAwF;QACxF,0FAA0F;QAC1F,2FAA2F;QAC3F,wFAAwF;QACxF,gDAAgD;QAChD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,mFAAmF;QACnF,sBAAsB;QACtB,IAAI,CAAC,oBAAoB,EAAE,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,oBAAoB,EAAE,OAAO,EAAE,CAAC;QACrC,IAAI,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,kBAAkB,EAAE,OAAO,EAAE,CAAC;QACnC,IAAI,CAAC,qBAAqB,EAAE,OAAO,EAAE,CAAC;QACtC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACjC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBAC/B,CAAC,CAAC,OAAO,EAAE,CAAC;YAChB,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,IAAI,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACpC,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QAEnB,uDAAuD;QACvD,MAAM,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAC/C,IAAI,aAAa,EAAE,CAAC;YAChB,aAAa,CAAC,OAAO,EAAE,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QAEvB,6FAA6F;QAC7F,oFAAoF;QACpF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,uCAAuC;YACvC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACvB,OAAO;QACX,CAAC;QAED,uFAAuF;QACvF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC;YACD,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC/C,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAE3E,4CAA4C;YAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC/B,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC;gBAExC,4EAA4E;gBAC5E,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;gBACnE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBAC9D,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;gBACpC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACpF,QAAQ,CAAC,kBAAkB,GAAG,UAAU,CAAC;gBACzC,QAAQ,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;gBAElC,oFAAoF;gBACpF,QAAQ,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;gBACvC,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;gBACvG,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC;gBAE3C,8EAA8E;gBAC9E,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC;YAED,+DAA+D;YAC/D,iDAAiD;YACjD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,yFAAyF;YACzF,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAwB,CAAC;YACzD,kBAAkB,EAAE,WAAW,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClH,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,6EAA6E;YAC7E,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YAC7B,MAAM,CAAC,CAAC;QACZ,CAAC;IACL,CAAC;IAED;;;;;;OAMG;IACa,SAAS,CAAC,sBAA2B,EAAE,EAAE,WAAmB,QAAQ;QAChF,mBAAmB,GAAG,KAAK,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;QAC3D,mBAAmB,CAAC,SAAS,GAAG,EAAE,CAAC;QACnC,mBAAmB,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACjD,mBAAmB,CAAC,UAAU,GAAG,SAAS,CAAC;QAC3C,mBAAmB,CAAC,gBAAgB,GAAG,SAAS,CAAC;QACjD,mBAAmB,CAAC,UAAU,GAAG,SAAS,CAAC;QAC3C,mBAAmB,CAAC,SAAS,GAAG,EAAE,CAAC;QACnC,mBAAmB,CAAC,OAAO,GAAG,SAAS,CAAC;QACxC,mBAAmB,CAAC,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAC/C,mBAAmB,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAChD,mBAAmB,CAAC,gBAAgB,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAC9D,mBAAmB,CAAC,mBAAmB,GAAG,IAAI,CAAC,mBAAmB,CAAC;QACnE,mBAAmB,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAEzC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnB,mBAAmB,CAAC,UAAU,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5H,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,mBAAmB,CAAC,MAAM,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QACpH,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,iBAAiB,GAAG,mBAAmB,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YAChG,mBAAmB,CAAC,WAAW,GAAG,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC;QAC/H,CAAC;QACD,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;YAC3B,mBAAmB,CAAC,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;QACrH,CAAC;QAED,OAAO,mBAAmB,CAAC;IAC/B,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,cAAc,CACxB,UAAe,EACf,KAAY,EACZ,IAAgG;QAEhG,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;QAE1E,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,gBAAgB,IAAI,KAAK,CAAC;QAC7D,IAAI,CAAC,mBAAmB,GAAG,UAAU,CAAC,mBAAmB,IAAI,yBAAyB,CAAC,2BAA2B,CAAC;QAEnH,IAAI,UAAU,GAAqC,UAAU,CAAC,UAAU,CAAC;QACzE,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;YACjC,UAAU,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,MAAM,GAAwC,UAAU,CAAC,MAAM,CAAC;QACtE,IAAI,YAAsC,CAAC;QAC3C,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,OAAO,GAAiB,EAAE,CAAC;YACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;gBACvB,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,UAAU,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC5D,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;gBACtB,CAAC;YACL,CAAC;YACD,YAAY,GAAG,OAAO,CAAC;QAC3B,CAAC;QAED,IAAI,WAAW,GAAgD,UAAU,CAAC,WAAW,CAAC;QACtF,IAAI,iBAAyC,CAAC;QAC9C,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YAClC,WAAW,GAAG,IAAI,WAAW,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,WAAW,EAAE,CAAC;YACd,iBAAiB,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC;YACzC,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,iBAAiB,CAAC,CAAC;QAC5E,CAAC;QAED,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;YACzB,KAAK,MAAM,cAAc,IAAI,UAAU,CAAC,WAAW,EAAE,CAAC;gBAClD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;gBAC/C,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;gBAC9B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAmC,CAAC;gBAChF,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC;gBACzC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,SAAS,CAAC;gBAC5C,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,SAAS,CAAC,cAAc,EAAE,CAAC,CAAC;gBACrE,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;;OAKG;IACI,MAAM,CAAU,KAAK,CAAC,UAAe,EAAE,KAAY;QACtD,OAAO,qBAAqB,CAAC,cAAc,CAAC,UAAU,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC1F,CAAC;CACJ;AAED,IAAI,CAAC,4BAA4B,GAAG,qBAAqB,CAAC,KAAK,CAAC","sourcesContent":["import { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Matrix, type Vector2, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect\";\r\n\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial\";\r\nimport { GaussianSplattingMeshBase } from \"./gaussianSplattingMeshBase\";\r\n\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DecodeBase64ToBinary, EncodeArrayBufferToBase64 } from \"core/Misc/stringTools\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport \"core/Meshes/thinInstanceMesh\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh\";\r\nimport { type BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\n\r\nconst _GaussianSplattingBytesPerSplat = 32;\r\nconst _GaussianSplattingBytesPerShTexel = 16;\r\n\r\ninterface IGaussianSplattingPartSource {\r\n name: string;\r\n _vertexCount: number;\r\n _splatsData: Nullable<ArrayBuffer>;\r\n _shData: Nullable<Uint8Array[]>;\r\n _shDegree: number;\r\n isCompound: boolean;\r\n getWorldMatrix(): Matrix;\r\n getBoundingInfo(): BoundingInfo;\r\n dispose(): void;\r\n}\r\n\r\n/**\r\n * Run-Length Encoding (RLE) compression for serialization\r\n * Compressed Uint32Array can be parsed using {@link ParsePartIndices}\r\n * Some notes for devs: We do not expect Uint8Array larger than 4GB,\r\n * so it should be safe to use Uint32Array.\r\n * @param partIndices A view of partIndices from GaussianSplattingMesh\r\n * @returns A compressed Uint32Array of [count, value, ...]\r\n */\r\nfunction CompressPartIndices(partIndices: Uint8Array): Uint32Array {\r\n const runs: number[] = [];\r\n const length = partIndices.length;\r\n let i = 0;\r\n while (i < length) {\r\n const value = partIndices[i];\r\n let count = 1;\r\n while (i + count < length && partIndices[i + count] === value) {\r\n count++;\r\n }\r\n runs.push(count, value);\r\n i += count;\r\n }\r\n return new Uint32Array(runs);\r\n}\r\n\r\n/**\r\n * Parse partIndices compressed by {@link CompressPartIndices} to runtime array\r\n * @param compressed The compressed partIndices of [count, value, ...]\r\n * @returns runtime Uint8Array for GaussianSplattingMesh\r\n */\r\nfunction ParsePartIndices(compressed: Uint32Array | number[]): Uint8Array {\r\n let totalCount = 0;\r\n const length = compressed.length;\r\n for (let i = 0; i < length; i += 2) {\r\n totalCount += compressed[i];\r\n }\r\n\r\n const partIndices = new Uint8Array(totalCount);\r\n let offset = 0;\r\n for (let i = 0; i < length; i += 2) {\r\n const count = compressed[i];\r\n const value = compressed[i + 1];\r\n partIndices.fill(value, offset, offset + count);\r\n offset += count;\r\n }\r\n\r\n return partIndices;\r\n}\r\n\r\n/**\r\n * Class used to render a Gaussian Splatting mesh. Supports both single-cloud and compound\r\n * (multi-part) rendering. In compound mode, multiple Gaussian Splatting source meshes are\r\n * merged into one draw call while retaining per-part world-matrix control via\r\n * addPart/addParts and removePart.\r\n */\r\nexport class GaussianSplattingMesh extends GaussianSplattingMeshBase {\r\n /**\r\n * Proxy meshes indexed by part index. Maintained in sync with _partMatrices.\r\n */\r\n private _partProxies: GaussianSplattingPartProxyMesh[] = [];\r\n\r\n /**\r\n * World matrices for each part, indexed by part index.\r\n */\r\n protected _partMatrices: Matrix[] = [];\r\n\r\n /** When true, suppresses the sort trigger inside setWorldMatrixForPart during batch rebuilds. */\r\n private _rebuilding: boolean = false;\r\n\r\n /**\r\n * Visibility values for each part (0.0 to 1.0), indexed by part index.\r\n */\r\n protected _partVisibility: number[] = [];\r\n\r\n private _partIndicesTexture: Nullable<BaseTexture> = null;\r\n private _partIndices: Nullable<Uint8Array> = null;\r\n\r\n /** Gets the part indices texture used for compound rendering */\r\n public get partIndicesTexture() {\r\n return this._partIndicesTexture;\r\n }\r\n\r\n /**\r\n * Creates a new GaussianSplattingMesh\r\n * @param name the name of the mesh\r\n * @param url optional URL to load a Gaussian Splatting file from\r\n * @param scene the hosting scene\r\n * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU\r\n * @param needsRotationScaleTextures generate rotation and scale matrix textures required for voxel-based IBL shadows\r\n */\r\n constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false, needsRotationScaleTextures: boolean = false) {\r\n super(name, url, scene, keepInRam);\r\n // Ensure _splatsData is retained once compound mode is entered — addPart/addParts need\r\n // the source data for full-texture rebuilds. Set after super() so it is visible to\r\n // _updateData when the async load completes.\r\n this._alwaysRetainSplatsData = true;\r\n this._needsRotationScaleTextures = needsRotationScaleTextures;\r\n }\r\n\r\n /**\r\n * Returns the class name\r\n * @returns \"GaussianSplattingMesh\"\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingMesh\";\r\n }\r\n\r\n /**\r\n * Disposes proxy meshes and clears part data in addition to the base class GPU resources.\r\n * @param doNotRecurse Set to true to not recurse into each children\r\n */\r\n public override dispose(doNotRecurse?: boolean): void {\r\n for (const proxy of this._partProxies) {\r\n proxy.dispose();\r\n }\r\n this._partIndicesTexture?.dispose();\r\n this._partProxies = [];\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._partIndicesTexture = null;\r\n super.dispose(doNotRecurse);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Worker and material hooks\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Posts the initial per-part data to the sort worker after it has been created.\r\n * Sends the current part matrices and group index array so the worker can correctly\r\n * weight depth values per part.\r\n * @param worker the newly created sort worker\r\n */\r\n protected override _onWorkerCreated(worker: Worker): void {\r\n worker.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n worker.postMessage({ partIndices: this._partIndices ? new Uint8Array(this._partIndices) : null });\r\n }\r\n\r\n /**\r\n * Stores the raw part index array, padded to texture length, so the worker and GPU texture\r\n * creation step have access to it.\r\n * @param partIndices - the raw part indices array received during a data load\r\n * @param textureLength - the padded texture length to allocate into\r\n */\r\n protected override _onIndexDataReceived(partIndices: Uint8Array, textureLength: number): void {\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndices);\r\n }\r\n\r\n /**\r\n * Returns `true` when at least one part has been added to this compound mesh.\r\n * Returns `false` before any parts are added, so the mesh renders in normal\r\n * (non-compound) mode until the first addPart/addParts call. This matches the\r\n * old base-class behavior of `this._partMatrices.length > 0` and avoids\r\n * binding unset partWorld uniforms (which would cause division-by-zero in the\r\n * Gaussian projection Jacobian and produce huge distorted splats).\r\n * @internal\r\n */\r\n public override get isCompound(): boolean {\r\n return this._partMatrices.length > 0;\r\n }\r\n\r\n /**\r\n * During a removePart rebuild, keep the existing sort worker alive rather than\r\n * tearing it down and spinning up a new one. This avoids startup latency and the\r\n * transient state window where a stale sort could fire against an incomplete\r\n * partMatrices array.\r\n * Outside of a rebuild the base-class behaviour is used unchanged.\r\n */\r\n protected override _instantiateWorker(): void {\r\n if (this._rebuilding && this._worker) {\r\n // Worker already exists and is kept alive; just resize the splat-index buffer.\r\n this._updateSplatIndexBuffer(this._vertexCount);\r\n return;\r\n }\r\n super._instantiateWorker();\r\n }\r\n\r\n /**\r\n * Ensures the part-index GPU texture exists at the start of an incremental update.\r\n * Called before the sub-texture upload so the correct texture is available for the first batch.\r\n * @param textureSize - current texture dimensions\r\n */\r\n protected override _onIncrementalUpdateStart(textureSize: Vector2): void {\r\n this._ensurePartIndicesTexture(textureSize, this._partIndices ?? undefined);\r\n }\r\n\r\n /**\r\n * Posts positions (via super) and then additionally posts the current part-index array\r\n * to the sort worker so it can associate each splat with its part.\r\n */\r\n protected override _notifyWorkerNewData(): void {\r\n super._notifyWorkerNewData();\r\n if (this._worker) {\r\n this._worker.postMessage({ partIndices: this._partIndices ?? null });\r\n }\r\n }\r\n\r\n /**\r\n * Binds all compound-specific shader uniforms: the group index texture, per-part world\r\n * matrices, and per-part visibility values.\r\n * @param effect the shader effect that is being bound\r\n * @internal\r\n */\r\n public override bindExtraEffectUniforms(effect: Effect): void {\r\n if (!this._partIndicesTexture) {\r\n return;\r\n }\r\n effect.setTexture(\"partIndicesTexture\", this._partIndicesTexture);\r\n const partWorldData = new Float32Array(this.partCount * 16);\r\n for (let i = 0; i < this.partCount; i++) {\r\n this._partMatrices[i].toArray(partWorldData, i * 16);\r\n }\r\n effect.setMatrices(\"partWorld\", partWorldData);\r\n const partVisibilityData: number[] = [];\r\n for (let i = 0; i < this.partCount; i++) {\r\n partVisibilityData.push(this._partVisibility[i] ?? 1.0);\r\n }\r\n effect.setArray(\"partVisibility\", partVisibilityData);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Part matrix / visibility management\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Gets the number of parts in the compound.\r\n */\r\n public get partCount(): number {\r\n return this._partMatrices.length;\r\n }\r\n\r\n /**\r\n * Gets the part visibility array.\r\n */\r\n public get partVisibility(): number[] {\r\n return this._partVisibility;\r\n }\r\n\r\n /**\r\n * Sets the world matrix for a specific part of the compound.\r\n * This will trigger a re-sort of the mesh.\r\n * The `_partMatrices` array is automatically extended when `partIndex >= partCount`.\r\n * @param partIndex index of the part\r\n * @param worldMatrix the world matrix to set\r\n */\r\n public setWorldMatrixForPart(partIndex: number, worldMatrix: Matrix): void {\r\n if (this._partMatrices.length <= partIndex) {\r\n this.computeWorldMatrix(true);\r\n const defaultMatrix = this.getWorldMatrix();\r\n while (this._partMatrices.length <= partIndex) {\r\n this._partMatrices.push(defaultMatrix.clone());\r\n this._partVisibility.push(1.0);\r\n }\r\n }\r\n this._partMatrices[partIndex].copyFrom(worldMatrix);\r\n // During a batch rebuild suppress intermediate posts — the final correct set is posted\r\n // once the full rebuild completes (at the end of removePart).\r\n if (!this._rebuilding) {\r\n if (this._worker) {\r\n this._worker.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n }\r\n this._postToWorker(true);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the world matrix for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the world matrix for the part, or the current world matrix of the mesh if the part is not found\r\n */\r\n public getWorldMatrixForPart(partIndex: number): Matrix {\r\n return this._partMatrices[partIndex] ?? this.getWorldMatrix();\r\n }\r\n\r\n /**\r\n * Gets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the visibility value (0.0 to 1.0) for the part\r\n */\r\n public getPartVisibility(partIndex: number): number {\r\n return this._partVisibility[partIndex] ?? 1.0;\r\n }\r\n\r\n /**\r\n * Sets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @param value the visibility value (0.0 to 1.0) to set\r\n */\r\n public setPartVisibility(partIndex: number, value: number): void {\r\n this._partVisibility[partIndex] = Math.max(0.0, Math.min(1.0, value));\r\n }\r\n\r\n protected override _copyTextures(source: GaussianSplattingMeshBase): void {\r\n super._copyTextures(source);\r\n this._partIndicesTexture = (source as GaussianSplattingMesh)._partIndicesTexture?.clone()!;\r\n }\r\n\r\n protected override _onUpdateTextures(textureSize: Vector2) {\r\n const createTextureFromDataU8 = (data: Uint8Array, width: number, height: number, format: number) => {\r\n return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n };\r\n\r\n // Keep the part indices texture in sync with _partIndices whenever textures are rebuilt.\r\n // The old \"only create if absent\" logic left the texture stale after a second addPart/addParts\r\n // call that doesn't change the texture dimensions: all new splats kept reading partIndex=0\r\n // (the first part), causing wrong positions, broken GPU picking, and shared movement.\r\n if (this._partIndices) {\r\n const buffer = new Uint8Array(this._partIndices);\r\n if (!this._partIndicesTexture) {\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n const existingSize = this._partIndicesTexture.getSize();\r\n if (existingSize.width !== textureSize.x || existingSize.height !== textureSize.y) {\r\n // Dimensions changed — dispose and recreate at the new size.\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n // Same size — update data in-place (e.g. second addParts fitting in existing dims).\r\n this._updateTextureFromData(this._partIndicesTexture, buffer, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected override _updateSubTextures(\r\n splatPositions: Float32Array,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n lineStart: number,\r\n lineCount: number,\r\n sh?: Uint8Array[],\r\n partIndices?: Uint8Array\r\n ): void {\r\n super._updateSubTextures(splatPositions, covA, covB, colorArray, lineStart, lineCount, sh);\r\n if (partIndices && this._partIndicesTexture) {\r\n const textureSize = this._getTextureSize(this._vertexCount);\r\n const texelStart = lineStart * textureSize.x;\r\n const texelCount = lineCount * textureSize.x;\r\n const partIndicesView = new Uint8Array(partIndices.buffer, texelStart, texelCount);\r\n this._updateTextureFromData(this._partIndicesTexture, partIndicesView, textureSize.x, lineStart, lineCount);\r\n\r\n if (this._worker) {\r\n this._worker.postMessage({ partIndices: partIndices });\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Creates the part indices GPU texture the first time an incremental addPart introduces\r\n * compound data. Has no effect if the texture already exists or no partIndices are provided.\r\n * @param textureSize - Current texture dimensions\r\n * @param partIndices - Part index data; if undefined the method is a no-op\r\n */\r\n protected _ensurePartIndicesTexture(textureSize: Vector2, partIndices: Uint8Array | undefined): void {\r\n if (!partIndices || this._partIndicesTexture) {\r\n return;\r\n }\r\n const buffer = new Uint8Array(this._partIndices!);\r\n this._partIndicesTexture = new RawTexture(\r\n buffer,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RED,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n );\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n if (this._worker) {\r\n this._worker.postMessage({ partIndices: partIndices ?? null });\r\n }\r\n }\r\n\r\n private _appendPartSourceToArrays(\r\n source: IGaussianSplattingPartSource,\r\n dstOffset: number,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n sh: Uint8Array[] | undefined,\r\n minimum: Vector3,\r\n maximum: Vector3\r\n ): void {\r\n this._appendSourceToArrays(source as unknown as GaussianSplattingMeshBase, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n }\r\n\r\n private _createRetainedPartSource(proxy: GaussianSplattingPartProxyMesh): Nullable<IGaussianSplattingPartSource> {\r\n if (!this._splatsData || (this._shDegree > 0 && !this._shData)) {\r\n return null;\r\n }\r\n\r\n const splatByteOffset = proxy._splatsDataOffset * _GaussianSplattingBytesPerSplat;\r\n const splatByteLength = proxy._vertexCount * _GaussianSplattingBytesPerSplat;\r\n const shByteOffset = proxy._shDataOffset * _GaussianSplattingBytesPerShTexel;\r\n const shByteLength = proxy._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n\r\n return {\r\n name: proxy.name,\r\n _vertexCount: proxy._vertexCount,\r\n _splatsData: this._splatsData.slice(splatByteOffset, splatByteOffset + splatByteLength),\r\n _shData: this._shData?.map((texture) => texture.slice(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n _shDegree: this._shData?.length ?? 0,\r\n isCompound: false,\r\n getWorldMatrix: () => proxy.getWorldMatrix(),\r\n getBoundingInfo: () => proxy.getBoundingInfo(),\r\n dispose: () => {},\r\n };\r\n }\r\n\r\n private _retainMergedPartData(existingVertexCount: number, totalCount: number, others: IGaussianSplattingPartSource[], shDegree: number): void {\r\n if (!this._keepInRam && !this._alwaysRetainSplatsData) {\r\n this._splatsData = null;\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n const getSourceBuffer = (data: ArrayBuffer): ArrayBuffer => {\r\n return data instanceof ArrayBuffer ? data : ((data as unknown as ArrayBufferView).buffer as ArrayBuffer);\r\n };\r\n\r\n const mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n let splatByteOffset = 0;\r\n\r\n if (this._splatsData && existingVertexCount > 0) {\r\n mergedSplatsData.set(new Uint8Array(getSourceBuffer(this._splatsData), 0, existingVertexCount * _GaussianSplattingBytesPerSplat), splatByteOffset);\r\n splatByteOffset += existingVertexCount * _GaussianSplattingBytesPerSplat;\r\n }\r\n\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n continue;\r\n }\r\n\r\n const splatByteLength = other._vertexCount * _GaussianSplattingBytesPerSplat;\r\n mergedSplatsData.set(new Uint8Array(getSourceBuffer(other._splatsData), 0, splatByteLength), splatByteOffset);\r\n splatByteOffset += splatByteLength;\r\n }\r\n\r\n this._splatsData = mergedSplatsData.buffer;\r\n\r\n if (shDegree <= 0) {\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n const mergedShData: Uint8Array[] = [];\r\n for (let textureIndex = 0; textureIndex < shDegree; textureIndex++) {\r\n mergedShData.push(new Uint8Array(totalCount * _GaussianSplattingBytesPerShTexel));\r\n }\r\n\r\n let shByteOffset = 0;\r\n if (this._shData && existingVertexCount > 0) {\r\n const existingShByteLength = existingVertexCount * _GaussianSplattingBytesPerShTexel;\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < this._shData.length) {\r\n mergedShData[textureIndex].set(this._shData[textureIndex].subarray(0, existingShByteLength), shByteOffset);\r\n }\r\n }\r\n shByteOffset += existingShByteLength;\r\n }\r\n\r\n for (const other of others) {\r\n const otherShByteLength = other._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n if (other._shData) {\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < other._shData.length) {\r\n mergedShData[textureIndex].set(other._shData[textureIndex].subarray(0, otherShByteLength), shByteOffset);\r\n }\r\n }\r\n }\r\n shByteOffset += otherShByteLength;\r\n }\r\n\r\n this._shData = mergedShData;\r\n }\r\n\r\n /**\r\n * Core implementation for adding one or more source parts as new\r\n * parts. Writes directly into texture-sized CPU arrays, updates the retained merged source\r\n * buffers, and uploads in one pass.\r\n *\r\n * @param others - Source meshes to append (must each be non-compound and fully loaded)\r\n * @param disposeOthers - Dispose source meshes after appending\r\n * @returns Proxy meshes and their assigned part indices\r\n */\r\n protected _addPartsInternal(others: IGaussianSplattingPartSource[], disposeOthers: boolean): { proxyMeshes: GaussianSplattingPartProxyMesh[]; assignedPartIndices: number[] } {\r\n if (others.length === 0) {\r\n return { proxyMeshes: [], assignedPartIndices: [] };\r\n }\r\n\r\n // Validate\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must be fully loaded`);\r\n }\r\n if (other.isCompound) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must not be a compound`);\r\n }\r\n }\r\n\r\n const splatCountA = this._vertexCount;\r\n const totalOtherCount = others.reduce((s, o) => s + o._vertexCount, 0);\r\n const totalCount = splatCountA + totalOtherCount;\r\n\r\n const textureSize = this._getTextureSize(totalCount);\r\n const textureLength = textureSize.x * textureSize.y;\r\n const covBSItemSize = this._useRGBACovariants ? 4 : 2;\r\n\r\n // Allocate destination arrays for the full new texture\r\n const covA = new Uint16Array(textureLength * 4);\r\n const covB = new Uint16Array(covBSItemSize * textureLength);\r\n const colorArray = new Uint8Array(textureLength * 4);\r\n\r\n // Determine merged SH degree\r\n const hasSH = this._shData !== null && others.every((o) => o._shData !== null);\r\n const shDegreeNew = hasSH ? Math.max(this._shDegree, ...others.map((o) => o._shDegree)) : 0;\r\n let sh: Uint8Array[] | undefined = undefined;\r\n if (hasSH && shDegreeNew > 0) {\r\n const bytesPerTexel = 16;\r\n sh = [];\r\n for (let i = 0; i < shDegreeNew; i++) {\r\n sh.push(new Uint8Array(textureLength * bytesPerTexel));\r\n }\r\n }\r\n\r\n // --- Incremental path: can we reuse the already-committed GPU region? ---\r\n const incremental = this._canReuseCachedData(splatCountA, totalCount);\r\n const firstNewLine = incremental ? Math.floor(splatCountA / textureSize.x) : 0;\r\n\r\n const minimum = incremental ? this._cachedBoundingMin!.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const maximum = incremental ? this._cachedBoundingMax!.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Preserve existing processed positions in the new array\r\n const oldPositions = this._splatPositions;\r\n this._splatPositions = new Float32Array(4 * textureLength);\r\n if (incremental && oldPositions) {\r\n this._splatPositions.set(oldPositions.subarray(0, splatCountA * 4));\r\n }\r\n\r\n // --- Build part indices ---\r\n let nextPartIndex = this.partCount;\r\n let partIndicesA = this._partIndices;\r\n if (!partIndicesA) {\r\n // First addPart on a plain mesh: assign its splats to part 0\r\n partIndicesA = new Uint8Array(splatCountA);\r\n nextPartIndex = splatCountA > 0 ? 1 : 0;\r\n }\r\n\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndicesA.subarray(0, splatCountA));\r\n\r\n const assignedPartIndices: number[] = [];\r\n const assignedSplatsDataOffsets: number[] = [];\r\n let dstOffset = splatCountA;\r\n const maxPartCount = GetGaussianSplattingMaxPartCount(this._scene.getEngine());\r\n for (const other of others) {\r\n if (nextPartIndex >= maxPartCount) {\r\n throw new Error(`Cannot add part, as the maximum part count (${maxPartCount}) has been reached`);\r\n }\r\n const newPartIndex = nextPartIndex++;\r\n assignedPartIndices.push(newPartIndex);\r\n assignedSplatsDataOffsets.push(dstOffset);\r\n this._partIndices.fill(newPartIndex, dstOffset, dstOffset + other._vertexCount);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // --- Process source data ---\r\n if (!incremental) {\r\n // Full rebuild path — only reached when the GPU texture must be reallocated\r\n // (either the texture height needs to grow to fit the new total, or this is\r\n // the very first addPart onto a mesh with no GPU textures yet). In the common\r\n // case where the texture height is unchanged, `incremental` is true and this\r\n // entire block is skipped. The `splatCountA > 0` guard avoids redundant work\r\n // on the first-ever addPart when the compound mesh starts empty.\r\n if (splatCountA > 0) {\r\n if (this._partProxies.length > 0) {\r\n // Already compound: rebuild every existing part from its stored source data.\r\n //\r\n // DESIGN NOTE: The intended use of GaussianSplattingMesh / GaussianSplattingCompoundMesh\r\n // in compound mode is to start EMPTY and compose parts exclusively via addPart/addParts.\r\n // In a future major version this will be the only supported path and the \"own data\"\r\n // legacy branch below will be removed.\r\n //\r\n // Until then, two layouts are possible:\r\n // A) LEGACY — compound loaded its own splat data (via URL or updateData) before\r\n // any addPart call. _partProxies[0] is undefined; the mesh's own splat data\r\n // is treated as an implicit \"part 0\" in this._splatsData. Proxied parts occupy\r\n // indices 1+. This layout will be deprecated in the next major version.\r\n // B) PREFERRED — compound started empty; first addPart assigned partIndex=0.\r\n // _partProxies[0] is set; this._splatsData is null; all parts are proxied.\r\n let rebuildOffset = 0;\r\n\r\n // Rebuild the compound's legacy \"own\" data at part 0 (scenario A only).\r\n // Skipped in the preferred empty-composer path (scenario B).\r\n if (!this._partProxies[0] && this._splatsData) {\r\n const proxyVertexCount = this._partProxies.reduce((sum, proxy) => sum + (proxy ? proxy._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyVertexCount;\r\n if (part0Count > 0) {\r\n const uBufA = new Uint8Array(this._splatsData);\r\n const fBufA = new Float32Array(this._splatsData);\r\n for (let i = 0; i < part0Count; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n const bytesPerTexel = 16;\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, part0Count * bytesPerTexel), 0);\r\n }\r\n }\r\n }\r\n rebuildOffset += part0Count;\r\n }\r\n }\r\n\r\n // Rebuild all proxied parts. Loop from index 0 because in the preferred\r\n // scenario B, part 0 is itself a proxied part with no implicit \"own\" data.\r\n for (let partIndex = 0; partIndex < this._partProxies.length; partIndex++) {\r\n const proxy = this._partProxies[partIndex];\r\n if (!proxy) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n this._appendPartSourceToArrays(source, rebuildOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n rebuildOffset += source._vertexCount;\r\n }\r\n } else {\r\n // No proxies yet: this is the very first addPart call on a mesh that loaded\r\n // its own splat data (scenario A legacy path). Re-process that own data so\r\n // it occupies the start of the new texture before the incoming part is appended.\r\n // In the preferred scenario B (empty composer) splatCountA is 0 and this\r\n // entire branch is skipped by the outer `if (splatCountA > 0)` guard.\r\n if (this._splatsData) {\r\n const uBufA = new Uint8Array(this._splatsData);\r\n const fBufA = new Float32Array(this._splatsData);\r\n for (let i = 0; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n const bytesPerTexel = 16;\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, splatCountA * bytesPerTexel), 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Incremental path: rebuild the partial first row (indices firstNewTexel to splatCountA-1)\r\n // so _updateSubTextures does not upload stale zeros over those already-committed texels.\r\n // The base-class _updateData always re-processes from firstNewTexel for the same reason;\r\n // the compound path must do the same.\r\n if (incremental) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n if (this._partProxies.length === 0) {\r\n // No proxies: the mesh loaded its own splat data and this is the first\r\n // addPart call (scenario A legacy path). Re-process the partial boundary\r\n // row so it is not clobbered by stale zeros during the sub-texture upload.\r\n if (this._splatsData) {\r\n const uBufA = new Uint8Array(this._splatsData);\r\n const fBufA = new Float32Array(this._splatsData);\r\n for (let i = firstNewTexel; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false, i);\r\n }\r\n }\r\n } else {\r\n // Already compound: build a per-partIndex source lookup so each splat in the\r\n // partial boundary row can be re-processed from its original source buffer.\r\n //\r\n // Handles both layouts (see full-rebuild comment above):\r\n // A) LEGACY: _partProxies[0] absent → seed lookup[0] with this._splatsData\r\n // B) PREFERRED: _partProxies[0] present → all entries filled from proxies\r\n const proxyTotal = this._partProxies.reduce((s, p) => s + (p ? p._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyTotal; // > 0 only in legacy scenario A\r\n const srcUBufs: (Uint8Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const srcFBufs: (Float32Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const partStarts: number[] = new Array(this._partProxies.length).fill(0);\r\n // Legacy scenario A: part 0 is the mesh's own loaded data.\r\n if (!this._partProxies[0] && this._splatsData && part0Count > 0) {\r\n srcUBufs[0] = new Uint8Array(this._splatsData);\r\n srcFBufs[0] = new Float32Array(this._splatsData);\r\n partStarts[0] = 0;\r\n }\r\n // All proxied parts — start from pi=0 to cover preferred scenario B.\r\n let cumOffset = part0Count;\r\n for (let pi = 0; pi < this._partProxies.length; pi++) {\r\n const proxy = this._partProxies[pi];\r\n if (!proxy) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source || !source._splatsData) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n srcUBufs[pi] = new Uint8Array(source._splatsData);\r\n srcFBufs[pi] = new Float32Array(source._splatsData);\r\n partStarts[pi] = cumOffset;\r\n cumOffset += source._vertexCount;\r\n }\r\n for (let splatIdx = firstNewTexel; splatIdx < splatCountA; splatIdx++) {\r\n const partIdx = this._partIndices ? this._partIndices[splatIdx] : 0;\r\n const uBuf = partIdx < srcUBufs.length ? srcUBufs[partIdx] : null;\r\n const fBuf = partIdx < srcFBufs.length ? srcFBufs[partIdx] : null;\r\n if (uBuf && fBuf) {\r\n this._makeSplat(splatIdx, fBuf, uBuf, covA, covB, colorArray, minimum, maximum, false, splatIdx - (partStarts[partIdx] ?? 0));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Append each new source\r\n dstOffset = splatCountA;\r\n for (const other of others) {\r\n this._appendPartSourceToArrays(other, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // Pad empty splats to texture boundary\r\n const paddedEnd = (totalCount + 15) & ~0xf;\r\n for (let i = totalCount; i < paddedEnd; i++) {\r\n this._makeEmptySplat(i, covA, covB, colorArray);\r\n }\r\n\r\n // --- Update vertex count / index buffer ---\r\n if (totalCount !== this._vertexCount) {\r\n this._updateSplatIndexBuffer(totalCount);\r\n }\r\n this._retainMergedPartData(splatCountA, totalCount, others, shDegreeNew);\r\n this._vertexCount = totalCount;\r\n this._shDegree = shDegreeNew;\r\n\r\n // Gate the sort worker for the duration of this operation. _updateTextures (below) may create the worker and fire an\r\n // immediate sort via _postToWorker. At that point partMatrices has not yet been updated for the incoming parts, so the\r\n // worker would compute depthCoeffs for fewer parts than partIndices references — crashing with\r\n // \"Cannot read properties of undefined (reading '0')\".\r\n // When called from removePart, _rebuilding is already true and _canPostToWorker is already false, so the gate is a\r\n // no-op — removePart handles the final post+sort.\r\n const needsWorkerGate = !this._rebuilding;\r\n if (needsWorkerGate) {\r\n this._canPostToWorker = false;\r\n this._rebuilding = true;\r\n }\r\n\r\n try {\r\n // --- Upload to GPU ---\r\n if (incremental) {\r\n // Update the part-indices texture (handles both create and update-in-place).\r\n // _ensurePartIndicesTexture is a no-op when the texture already exists, so on the\r\n // second+ addPart the partIndices would be stale without this call.\r\n this._onUpdateTextures(textureSize);\r\n this._updateSubTextures(this._splatPositions, covA, covB, colorArray, firstNewLine, textureSize.y - firstNewLine, sh);\r\n } else {\r\n this._updateTextures(covA, covB, colorArray, sh);\r\n }\r\n\r\n this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());\r\n this.setEnabled(true);\r\n this._cachedBoundingMin = minimum.clone();\r\n this._cachedBoundingMax = maximum.clone();\r\n this._notifyWorkerNewData();\r\n\r\n // --- Create proxy meshes ---\r\n const proxyMeshes: GaussianSplattingPartProxyMesh[] = [];\r\n for (let i = 0; i < others.length; i++) {\r\n const other = others[i];\r\n const newPartIndex = assignedPartIndices[i];\r\n\r\n const partWorldMatrix = other.getWorldMatrix();\r\n this.setWorldMatrixForPart(newPartIndex, partWorldMatrix);\r\n\r\n const proxyMesh = new GaussianSplattingPartProxyMesh(\r\n other.name,\r\n this.getScene(),\r\n this,\r\n newPartIndex,\r\n other.getBoundingInfo(),\r\n other._vertexCount,\r\n assignedSplatsDataOffsets[i],\r\n assignedSplatsDataOffsets[i]\r\n );\r\n\r\n if (disposeOthers) {\r\n other.dispose();\r\n }\r\n\r\n const quaternion = new Quaternion();\r\n partWorldMatrix.decompose(proxyMesh.scaling, quaternion, proxyMesh.position);\r\n proxyMesh.rotationQuaternion = quaternion;\r\n proxyMesh.computeWorldMatrix(true);\r\n\r\n this._partProxies[newPartIndex] = proxyMesh;\r\n proxyMeshes.push(proxyMesh);\r\n }\r\n\r\n // Restore the rebuild gate and post the now-complete partMatrices in one message, then trigger a single sort pass.\r\n // This ensures the worker sees a consistent partMatrices array that matches the partIndices for every splat.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n if (this._worker) {\r\n this._worker.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n }\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n }\r\n\r\n return { proxyMeshes, assignedPartIndices };\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Public compound API\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Add another mesh to this mesh, as a new part. This makes the current mesh a compound, if not already.\r\n * The source mesh's splat data is read directly and copied into the compound's retained source buffers.\r\n * @param other - The other mesh to add. Must be fully loaded before calling this method.\r\n * @param disposeOther - Whether to dispose the other mesh after adding it to the current mesh.\r\n * @returns a placeholder mesh that can be used to manipulate the part transform\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.addPart} instead.\r\n */\r\n public addPart(other: GaussianSplattingMesh, disposeOther: boolean = true): GaussianSplattingPartProxyMesh {\r\n const { proxyMeshes } = this._addPartsInternal([other], disposeOther);\r\n return proxyMeshes[0];\r\n }\r\n\r\n /**\r\n * Remove a part from this compound mesh.\r\n * The remaining parts are rebuilt directly from the compound mesh's retained source buffers.\r\n * The current mesh is reset to a plain (single-part) state and then each remaining source is\r\n * re-added via addParts.\r\n * @param index - The index of the part to remove\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.removePart} instead.\r\n */\r\n public removePart(index: number): void {\r\n if (index < 0 || index >= this.partCount) {\r\n throw new Error(`Part index ${index} is out of range [0, ${this.partCount})`);\r\n }\r\n\r\n // Collect surviving proxy objects (sorted by current part index so part 0 is added first)\r\n const survivors: Array<{ proxyMesh: GaussianSplattingPartProxyMesh; source: IGaussianSplattingPartSource; oldIndex: number; worldMatrix: Matrix; visibility: number }> = [];\r\n for (let proxyIndex = 0; proxyIndex < this._partProxies.length; proxyIndex++) {\r\n const proxy = this._partProxies[proxyIndex];\r\n if (!proxy || proxyIndex === index) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot remove part: the retained compound source data is not available for part \"${proxy.name}\".`);\r\n }\r\n survivors.push({ proxyMesh: proxy, source, oldIndex: proxyIndex, worldMatrix: proxy.getWorldMatrix().clone(), visibility: this._partVisibility[proxyIndex] ?? 1.0 });\r\n }\r\n survivors.sort((a, b) => a.oldIndex - b.oldIndex);\r\n\r\n // Validate every survivor still has its source data. If even one is missing we cannot rebuild.\r\n for (const { proxyMesh, source } of survivors) {\r\n if (!source._splatsData) {\r\n throw new Error(`Cannot remove part: the source data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n if (source._shDegree > 0 && !source._shData) {\r\n throw new Error(`Cannot remove part: the SH data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n }\r\n\r\n // --- Reset this mesh to an empty state ---\r\n // Terminate the sort worker before zeroing _vertexCount. The worker's onmessage handler\r\n // compares depthMix.length against (_vertexCount + 15) & ~0xf; with _vertexCount = 0 that\r\n // becomes 16, which causes a forced re-sort loop on stale data and resets _canPostToWorker\r\n // to true, defeating the gate below. The worker will be re-instantiated naturally after\r\n // the rebuild via the first _postToWorker call.\r\n if (this._worker) {\r\n this._worker.terminate();\r\n this._worker = null;\r\n }\r\n // Dispose and null GPU textures so _updateTextures sees firstTime=true and creates\r\n // fresh GPU textures.\r\n this._covariancesATexture?.dispose();\r\n this._covariancesBTexture?.dispose();\r\n this._centersTexture?.dispose();\r\n this._colorsTexture?.dispose();\r\n this._rotationsATexture?.dispose();\r\n this._rotationsBTexture?.dispose();\r\n this._rotationScaleTexture?.dispose();\r\n this._covariancesATexture = null;\r\n this._covariancesBTexture = null;\r\n this._centersTexture = null;\r\n this._colorsTexture = null;\r\n this._rotationsATexture = null;\r\n this._rotationsBTexture = null;\r\n this._rotationScaleTexture = null;\r\n if (this._shTextures) {\r\n for (const t of this._shTextures) {\r\n t.dispose();\r\n }\r\n this._shTextures = null;\r\n }\r\n if (this._partIndicesTexture) {\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = null;\r\n }\r\n this._vertexCount = 0;\r\n this._splatPositions = null;\r\n this._partIndices = null;\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._cachedBoundingMin = null;\r\n this._cachedBoundingMax = null;\r\n this._splatsData = null;\r\n this._shData = null;\r\n this._shDegree = 0;\r\n\r\n // Remove the proxy for the removed part and dispose it\r\n const proxyToRemove = this._partProxies[index];\r\n if (proxyToRemove) {\r\n proxyToRemove.dispose();\r\n }\r\n this._partProxies = [];\r\n\r\n // Rebuild from surviving sources. _addPartsInternal assigns part indices in order 0, 1, 2, …\r\n // so the new index for each survivor is simply its position in the survivors array.\r\n if (survivors.length === 0) {\r\n // Nothing left — leave the mesh empty.\r\n this.setEnabled(false);\r\n return;\r\n }\r\n\r\n // Gate the sort worker: suppress any sort request until the full rebuild is committed.\r\n this._rebuilding = true;\r\n this._canPostToWorker = false;\r\n try {\r\n const sources = survivors.map((s) => s.source);\r\n const { proxyMeshes: newProxies } = this._addPartsInternal(sources, false);\r\n\r\n // Restore world matrices and re-map proxies\r\n for (let i = 0; i < survivors.length; i++) {\r\n const oldProxy = survivors[i].proxyMesh;\r\n const newProxy = newProxies[i];\r\n const newPartIndex = newProxy.partIndex;\r\n\r\n // Restore the world matrix and visibility the user had set on the old proxy\r\n this.setWorldMatrixForPart(newPartIndex, survivors[i].worldMatrix);\r\n this.setPartVisibility(newPartIndex, survivors[i].visibility);\r\n const quaternion = new Quaternion();\r\n survivors[i].worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n newProxy.rotationQuaternion = quaternion;\r\n newProxy.computeWorldMatrix(true);\r\n\r\n // Update the old proxy's index and metadata so existing user references still work.\r\n oldProxy.updatePartIndex(newPartIndex);\r\n oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n this._partProxies[newPartIndex] = oldProxy;\r\n\r\n // newProxy is redundant — it was created inside _addPartsInternal; dispose it\r\n newProxy.dispose();\r\n }\r\n\r\n // Rebuild is complete: all partMatrices are now set correctly.\r\n // Post the final complete set and fire one sort.\r\n this._rebuilding = false;\r\n // Break TypeScript's flow narrowing — _addPartsInternal may have reinstantiated _worker.\r\n const workerAfterRebuild = this._worker as Worker | null;\r\n workerAfterRebuild?.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Serialize current GaussianSplattingMesh\r\n * @param serializationObject defines the object which will receive the serialization data\r\n * @param encoding the encoding of binary data, defaults to base64 for json serialize,\r\n * kept for future internal use like cloning where base64 encoding wastes cycles and memory\r\n * @returns the serialized object\r\n */\r\n public override serialize(serializationObject: any = {}, encoding: string = \"base64\"): any {\r\n serializationObject = super.serialize(serializationObject);\r\n serializationObject.subMeshes = [];\r\n serializationObject.geometryUniqueId = undefined;\r\n serializationObject.geometryId = undefined;\r\n serializationObject.materialUniqueId = undefined;\r\n serializationObject.materialId = undefined;\r\n serializationObject.instances = [];\r\n serializationObject.actions = undefined;\r\n serializationObject.type = this.getClassName();\r\n serializationObject.keepInRam = this._keepInRam;\r\n serializationObject.disableDepthSort = this._disableDepthSort;\r\n serializationObject.viewUpdateThreshold = this.viewUpdateThreshold;\r\n serializationObject._flipY = this._flipY;\r\n\r\n if (this._splatsData) {\r\n serializationObject.splatsData = encoding === \"base64\" ? EncodeArrayBufferToBase64(this._splatsData) : this._splatsData;\r\n }\r\n if (this._shData) {\r\n serializationObject.shData = encoding === \"base64\" ? this._shData.map(EncodeArrayBufferToBase64) : this._shData;\r\n }\r\n if (this._partIndices) {\r\n const compressedIndices = CompressPartIndices(this._partIndices.subarray(0, this._vertexCount));\r\n serializationObject.partIndices = encoding === \"base64\" ? EncodeArrayBufferToBase64(compressedIndices) : compressedIndices;\r\n }\r\n if (this._partProxies.length) {\r\n serializationObject.partProxies = this._partProxies.filter((proxy) => !!proxy).map((proxy) => proxy.serialize());\r\n }\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Internal helper to parses a serialized GaussianSplattingMesh or GaussianSplattingCompoundMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh or GaussianSplattingCompoundMesh in\r\n * @param ctor the constructor of the mesh to create\r\n * @returns the created GaussianSplattingMesh\r\n * @internal\r\n */\r\n public static _ParseInternal<T extends GaussianSplattingMesh>(\r\n parsedMesh: any,\r\n scene: Scene,\r\n ctor: new (name: string, url: Nullable<string>, scene: Nullable<Scene>, keepInRam: boolean) => T\r\n ): T {\r\n const mesh = new ctor(parsedMesh.name, null, scene, parsedMesh.keepInRam);\r\n\r\n mesh.disableDepthSort = parsedMesh.disableDepthSort ?? false;\r\n mesh.viewUpdateThreshold = parsedMesh.viewUpdateThreshold ?? GaussianSplattingMeshBase._DefaultViewUpdateThreshold;\r\n\r\n let splatsData: ArrayBuffer | string | undefined = parsedMesh.splatsData;\r\n if (typeof splatsData === \"string\") {\r\n splatsData = DecodeBase64ToBinary(splatsData);\r\n }\r\n\r\n const shData: string[] | Uint8Array[] | undefined = parsedMesh.shData;\r\n let parsedShData: Uint8Array[] | undefined;\r\n if (Array.isArray(shData) && shData.length) {\r\n const newData: Uint8Array[] = [];\r\n for (let i = 0, length = shData.length; i < length; i++) {\r\n const data = shData[i];\r\n if (typeof data === \"string\") {\r\n newData[i] = new Uint8Array(DecodeBase64ToBinary(data));\r\n } else {\r\n newData[i] = data;\r\n }\r\n }\r\n parsedShData = newData;\r\n }\r\n\r\n let partIndices: string | Uint32Array | number[] | undefined = parsedMesh.partIndices;\r\n let parsedPartIndices: Uint8Array | undefined;\r\n if (typeof partIndices === \"string\") {\r\n partIndices = new Uint32Array(DecodeBase64ToBinary(partIndices));\r\n }\r\n if (partIndices) {\r\n parsedPartIndices = ParsePartIndices(partIndices);\r\n }\r\n\r\n if (splatsData) {\r\n const flipY = parsedMesh._flipY ?? false;\r\n mesh.updateData(splatsData, parsedShData, { flipY }, parsedPartIndices);\r\n }\r\n\r\n if (parsedMesh.partProxies) {\r\n for (const serializedPart of parsedMesh.partProxies) {\r\n const part = Object.assign({}, serializedPart);\r\n part.compoundSplatMesh = mesh;\r\n const proxyMesh = Mesh.Parse(part, scene, \"\") as GaussianSplattingPartProxyMesh;\r\n const newPartIndex = proxyMesh.partIndex;\r\n mesh._partProxies[newPartIndex] = proxyMesh;\r\n mesh.setWorldMatrixForPart(newPartIndex, proxyMesh.getWorldMatrix());\r\n mesh.setPartVisibility(newPartIndex, proxyMesh.visibility);\r\n }\r\n }\r\n\r\n return mesh;\r\n }\r\n\r\n /**\r\n * Parses a serialized GaussianSplattingMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh in\r\n * @returns the created GaussianSplattingMesh\r\n */\r\n public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingMesh {\r\n return GaussianSplattingMesh._ParseInternal(parsedMesh, scene, GaussianSplattingMesh);\r\n }\r\n}\r\n\r\nMesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n"]}
1
+ {"version":3,"file":"gaussianSplattingMesh.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Matrix, type Vector2, Quaternion, Vector3 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect\";\r\n\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial\";\r\nimport { GaussianSplattingMeshBase } from \"./gaussianSplattingMeshBase\";\r\n\r\nimport { RawTexture } from \"core/Materials/Textures/rawTexture\";\r\nimport { Constants } from \"core/Engines/constants\";\r\nimport { DecodeBase64ToBinary, EncodeArrayBufferToBase64 } from \"core/Misc/stringTools\";\r\nimport { Mesh } from \"core/Meshes/mesh\";\r\nimport \"core/Meshes/thinInstanceMesh\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh\";\r\nimport { type BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture\";\r\n\r\nconst _GaussianSplattingBytesPerSplat = 32;\r\nconst _GaussianSplattingBytesPerShTexel = 16;\r\n\r\ninterface IGaussianSplattingPartSource {\r\n name: string;\r\n _vertexCount: number;\r\n _splatsData: Nullable<ArrayBuffer>;\r\n _shData: Nullable<Uint8Array[]>;\r\n _shDegree: number;\r\n isCompound: boolean;\r\n getWorldMatrix(): Matrix;\r\n getBoundingInfo(): BoundingInfo;\r\n dispose(): void;\r\n}\r\n\r\n/**\r\n * Run-Length Encoding (RLE) compression for serialization\r\n * Compressed Uint32Array can be parsed using {@link ParsePartIndices}\r\n * Some notes for devs: We do not expect Uint8Array larger than 4GB,\r\n * so it should be safe to use Uint32Array.\r\n * @param partIndices A view of partIndices from GaussianSplattingMesh\r\n * @returns A compressed Uint32Array of [count, value, ...]\r\n */\r\nfunction CompressPartIndices(partIndices: Uint8Array): Uint32Array {\r\n const runs: number[] = [];\r\n const length = partIndices.length;\r\n let i = 0;\r\n while (i < length) {\r\n const value = partIndices[i];\r\n let count = 1;\r\n while (i + count < length && partIndices[i + count] === value) {\r\n count++;\r\n }\r\n runs.push(count, value);\r\n i += count;\r\n }\r\n return new Uint32Array(runs);\r\n}\r\n\r\n/**\r\n * Parse partIndices compressed by {@link CompressPartIndices} to runtime array\r\n * @param compressed The compressed partIndices of [count, value, ...]\r\n * @returns runtime Uint8Array for GaussianSplattingMesh\r\n */\r\nfunction ParsePartIndices(compressed: Uint32Array | number[]): Uint8Array {\r\n let totalCount = 0;\r\n const length = compressed.length;\r\n for (let i = 0; i < length; i += 2) {\r\n totalCount += compressed[i];\r\n }\r\n\r\n const partIndices = new Uint8Array(totalCount);\r\n let offset = 0;\r\n for (let i = 0; i < length; i += 2) {\r\n const count = compressed[i];\r\n const value = compressed[i + 1];\r\n partIndices.fill(value, offset, offset + count);\r\n offset += count;\r\n }\r\n\r\n return partIndices;\r\n}\r\n\r\n/**\r\n * Class used to render a Gaussian Splatting mesh. Supports both single-cloud and compound\r\n * (multi-part) rendering. In compound mode, multiple Gaussian Splatting source meshes are\r\n * merged into one draw call while retaining per-part world-matrix control via\r\n * addPart/addParts and removePart.\r\n */\r\nexport class GaussianSplattingMesh extends GaussianSplattingMeshBase {\r\n /**\r\n * Proxy meshes indexed by part index. Maintained in sync with _partMatrices.\r\n */\r\n private _partProxies: GaussianSplattingPartProxyMesh[] = [];\r\n\r\n /**\r\n * World matrices for each part, indexed by part index.\r\n */\r\n protected _partMatrices: Matrix[] = [];\r\n\r\n /** When true, suppresses the sort trigger inside setWorldMatrixForPart during batch rebuilds. */\r\n private _rebuilding: boolean = false;\r\n\r\n /**\r\n * Visibility values for each part (0.0 to 1.0), indexed by part index.\r\n */\r\n protected _partVisibility: number[] = [];\r\n\r\n private _partIndicesTexture: Nullable<BaseTexture> = null;\r\n private _partIndices: Nullable<Uint8Array> = null;\r\n\r\n /** Gets the part indices texture used for compound rendering */\r\n public get partIndicesTexture() {\r\n return this._partIndicesTexture;\r\n }\r\n\r\n /**\r\n * Creates a new GaussianSplattingMesh\r\n * @param name the name of the mesh\r\n * @param url optional URL to load a Gaussian Splatting file from\r\n * @param scene the hosting scene\r\n * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU\r\n * @param needsRotationScaleTextures generate rotation and scale matrix textures required for voxel-based IBL shadows\r\n */\r\n constructor(name: string, url: Nullable<string> = null, scene: Nullable<Scene> = null, keepInRam: boolean = false, needsRotationScaleTextures: boolean = false) {\r\n super(name, url, scene, keepInRam);\r\n // Ensure _splatsData is retained once compound mode is entered — addPart/addParts need\r\n // the source data for full-texture rebuilds. Set after super() so it is visible to\r\n // _updateData when the async load completes.\r\n this._alwaysRetainSplatsData = true;\r\n this._needsRotationScaleTextures = needsRotationScaleTextures;\r\n }\r\n\r\n /**\r\n * Returns the class name\r\n * @returns \"GaussianSplattingMesh\"\r\n */\r\n public override getClassName(): string {\r\n return \"GaussianSplattingMesh\";\r\n }\r\n\r\n /**\r\n * Is this node ready to be used/rendered.\r\n * Force-syncs every part proxy's world matrix into `_partMatrices` BEFORE delegating to\r\n * the base readiness check. This guarantees that any pending proxy transform changes\r\n * (for example a user-set `proxy.position`) are reflected in the next sort post, so the\r\n * base `isReady` will only return true once `sortAppliedId === sortRequestId` for that\r\n * up-to-date state. Without this, the proxy's `onAfterWorldMatrixUpdateObservable` would\r\n * fire during the first render and queue a fresh sort AFTER readiness was reported,\r\n * leaving the rendered frame with stale splat order on `renderCount=1` runs.\r\n * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)\r\n * @returns true when ready\r\n */\r\n public override isReady(completeCheck = false): boolean {\r\n for (const proxy of this._partProxies) {\r\n if (proxy) {\r\n proxy.computeWorldMatrix(true);\r\n }\r\n }\r\n return super.isReady(completeCheck);\r\n }\r\n\r\n /**\r\n * Disposes proxy meshes and clears part data in addition to the base class GPU resources.\r\n * @param doNotRecurse Set to true to not recurse into each children\r\n */\r\n public override dispose(doNotRecurse?: boolean): void {\r\n for (const proxy of this._partProxies) {\r\n proxy.dispose();\r\n }\r\n this._partIndicesTexture?.dispose();\r\n this._partProxies = [];\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._partIndicesTexture = null;\r\n super.dispose(doNotRecurse);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Worker and material hooks\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Posts the initial per-part data to the sort worker after it has been created.\r\n * Sends the current part matrices and group index array so the worker can correctly\r\n * weight depth values per part.\r\n * @param worker the newly created sort worker\r\n */\r\n protected override _onWorkerCreated(worker: Worker): void {\r\n worker.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n worker.postMessage({ partIndices: this._partIndices ? new Uint8Array(this._partIndices) : null });\r\n }\r\n\r\n /**\r\n * Stores the raw part index array, padded to texture length, so the worker and GPU texture\r\n * creation step have access to it.\r\n * @param partIndices - the raw part indices array received during a data load\r\n * @param textureLength - the padded texture length to allocate into\r\n */\r\n protected override _onIndexDataReceived(partIndices: Uint8Array, textureLength: number): void {\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndices);\r\n }\r\n\r\n /**\r\n * Returns `true` when at least one part has been added to this compound mesh.\r\n * Returns `false` before any parts are added, so the mesh renders in normal\r\n * (non-compound) mode until the first addPart/addParts call. This matches the\r\n * old base-class behavior of `this._partMatrices.length > 0` and avoids\r\n * binding unset partWorld uniforms (which would cause division-by-zero in the\r\n * Gaussian projection Jacobian and produce huge distorted splats).\r\n * @internal\r\n */\r\n public override get isCompound(): boolean {\r\n return this._partMatrices.length > 0;\r\n }\r\n\r\n /**\r\n * During a removePart rebuild, keep the existing sort worker alive rather than\r\n * tearing it down and spinning up a new one. This avoids startup latency and the\r\n * transient state window where a stale sort could fire against an incomplete\r\n * partMatrices array.\r\n * Outside of a rebuild the base-class behaviour is used unchanged.\r\n */\r\n protected override _instantiateWorker(): void {\r\n if (this._rebuilding && this._worker) {\r\n // Worker already exists and is kept alive; just resize the splat-index buffer.\r\n this._updateSplatIndexBuffer(this._vertexCount);\r\n return;\r\n }\r\n super._instantiateWorker();\r\n }\r\n\r\n /**\r\n * Ensures the part-index GPU texture exists at the start of an incremental update.\r\n * Called before the sub-texture upload so the correct texture is available for the first batch.\r\n * @param textureSize - current texture dimensions\r\n */\r\n protected override _onIncrementalUpdateStart(textureSize: Vector2): void {\r\n this._ensurePartIndicesTexture(textureSize, this._partIndices ?? undefined);\r\n }\r\n\r\n /**\r\n * Posts positions (via super) and then additionally posts the current part-index array\r\n * to the sort worker so it can associate each splat with its part.\r\n */\r\n protected override _notifyWorkerNewData(): void {\r\n super._notifyWorkerNewData();\r\n if (this._worker) {\r\n this._worker.postMessage({ partIndices: this._partIndices ?? null });\r\n }\r\n }\r\n\r\n /**\r\n * Binds all compound-specific shader uniforms: the group index texture, per-part world\r\n * matrices, and per-part visibility values.\r\n * @param effect the shader effect that is being bound\r\n * @internal\r\n */\r\n public override bindExtraEffectUniforms(effect: Effect): void {\r\n if (!this._partIndicesTexture) {\r\n return;\r\n }\r\n effect.setTexture(\"partIndicesTexture\", this._partIndicesTexture);\r\n const partWorldData = new Float32Array(this.partCount * 16);\r\n for (let i = 0; i < this.partCount; i++) {\r\n this._partMatrices[i].toArray(partWorldData, i * 16);\r\n }\r\n effect.setMatrices(\"partWorld\", partWorldData);\r\n const partVisibilityData: number[] = [];\r\n for (let i = 0; i < this.partCount; i++) {\r\n partVisibilityData.push(this._partVisibility[i] ?? 1.0);\r\n }\r\n effect.setArray(\"partVisibility\", partVisibilityData);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Part matrix / visibility management\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Gets the number of parts in the compound.\r\n */\r\n public get partCount(): number {\r\n return this._partMatrices.length;\r\n }\r\n\r\n /**\r\n * Gets the part visibility array.\r\n */\r\n public get partVisibility(): number[] {\r\n return this._partVisibility;\r\n }\r\n\r\n /**\r\n * Sets the world matrix for a specific part of the compound.\r\n * This will trigger a re-sort of the mesh.\r\n * The `_partMatrices` array is automatically extended when `partIndex >= partCount`.\r\n * @param partIndex index of the part\r\n * @param worldMatrix the world matrix to set\r\n */\r\n public setWorldMatrixForPart(partIndex: number, worldMatrix: Matrix): void {\r\n if (this._partMatrices.length <= partIndex) {\r\n this.computeWorldMatrix(true);\r\n const defaultMatrix = this.getWorldMatrix();\r\n while (this._partMatrices.length <= partIndex) {\r\n this._partMatrices.push(defaultMatrix.clone());\r\n this._partVisibility.push(1.0);\r\n }\r\n }\r\n // Skip the post / sort if the matrix is unchanged. Babylon recomputes the proxy mesh's world matrix every frame\r\n // and fires onAfterWorldMatrixUpdateObservable, so without this guard a stable scene would queue a forced sort\r\n // every frame and `isReady()` would never settle (sortRequestId would keep advancing past sortAppliedId).\r\n if (this._partMatrices[partIndex].equals(worldMatrix)) {\r\n return;\r\n }\r\n this._partMatrices[partIndex].copyFrom(worldMatrix);\r\n // During a batch rebuild suppress intermediate posts — the final correct set is posted\r\n // once the full rebuild completes (at the end of removePart).\r\n if (!this._rebuilding) {\r\n if (this._worker) {\r\n this._worker.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n }\r\n this._postToWorker(true);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the world matrix for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the world matrix for the part, or the current world matrix of the mesh if the part is not found\r\n */\r\n public getWorldMatrixForPart(partIndex: number): Matrix {\r\n return this._partMatrices[partIndex] ?? this.getWorldMatrix();\r\n }\r\n\r\n /**\r\n * Gets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @returns the visibility value (0.0 to 1.0) for the part\r\n */\r\n public getPartVisibility(partIndex: number): number {\r\n return this._partVisibility[partIndex] ?? 1.0;\r\n }\r\n\r\n /**\r\n * Sets the visibility for a specific part of the compound.\r\n * @param partIndex index of the part, that must be between 0 and partCount - 1\r\n * @param value the visibility value (0.0 to 1.0) to set\r\n */\r\n public setPartVisibility(partIndex: number, value: number): void {\r\n this._partVisibility[partIndex] = Math.max(0.0, Math.min(1.0, value));\r\n }\r\n\r\n protected override _copyTextures(source: GaussianSplattingMeshBase): void {\r\n super._copyTextures(source);\r\n this._partIndicesTexture = (source as GaussianSplattingMesh)._partIndicesTexture?.clone()!;\r\n }\r\n\r\n protected override _onUpdateTextures(textureSize: Vector2) {\r\n const createTextureFromDataU8 = (data: Uint8Array, width: number, height: number, format: number) => {\r\n return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);\r\n };\r\n\r\n // Keep the part indices texture in sync with _partIndices whenever textures are rebuilt.\r\n // The old \"only create if absent\" logic left the texture stale after a second addPart/addParts\r\n // call that doesn't change the texture dimensions: all new splats kept reading partIndex=0\r\n // (the first part), causing wrong positions, broken GPU picking, and shared movement.\r\n if (this._partIndices) {\r\n const buffer = new Uint8Array(this._partIndices);\r\n if (!this._partIndicesTexture) {\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n const existingSize = this._partIndicesTexture.getSize();\r\n if (existingSize.width !== textureSize.x || existingSize.height !== textureSize.y) {\r\n // Dimensions changed — dispose and recreate at the new size.\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = createTextureFromDataU8(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RED);\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n } else {\r\n // Same size — update data in-place (e.g. second addParts fitting in existing dims).\r\n this._updateTextureFromData(this._partIndicesTexture, buffer, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n }\r\n }\r\n\r\n protected override _updateSubTextures(\r\n splatPositions: Float32Array,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n lineStart: number,\r\n lineCount: number,\r\n sh?: Uint8Array[],\r\n partIndices?: Uint8Array\r\n ): void {\r\n super._updateSubTextures(splatPositions, covA, covB, colorArray, lineStart, lineCount, sh);\r\n if (partIndices && this._partIndicesTexture) {\r\n const textureSize = this._getTextureSize(this._vertexCount);\r\n const texelStart = lineStart * textureSize.x;\r\n const texelCount = lineCount * textureSize.x;\r\n const partIndicesView = new Uint8Array(partIndices.buffer, texelStart, texelCount);\r\n this._updateTextureFromData(this._partIndicesTexture, partIndicesView, textureSize.x, lineStart, lineCount);\r\n\r\n if (this._worker) {\r\n this._worker.postMessage({ partIndices: partIndices });\r\n }\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Private helpers\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Creates the part indices GPU texture the first time an incremental addPart introduces\r\n * compound data. Has no effect if the texture already exists or no partIndices are provided.\r\n * @param textureSize - Current texture dimensions\r\n * @param partIndices - Part index data; if undefined the method is a no-op\r\n */\r\n protected _ensurePartIndicesTexture(textureSize: Vector2, partIndices: Uint8Array | undefined): void {\r\n if (!partIndices || this._partIndicesTexture) {\r\n return;\r\n }\r\n const buffer = new Uint8Array(this._partIndices!);\r\n this._partIndicesTexture = new RawTexture(\r\n buffer,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RED,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_BILINEAR_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_BYTE\r\n );\r\n this._partIndicesTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._partIndicesTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n if (this._worker) {\r\n this._worker.postMessage({ partIndices: partIndices ?? null });\r\n }\r\n }\r\n\r\n private _appendPartSourceToArrays(\r\n source: IGaussianSplattingPartSource,\r\n dstOffset: number,\r\n covA: Uint16Array,\r\n covB: Uint16Array,\r\n colorArray: Uint8Array,\r\n sh: Uint8Array[] | undefined,\r\n minimum: Vector3,\r\n maximum: Vector3\r\n ): void {\r\n this._appendSourceToArrays(source as unknown as GaussianSplattingMeshBase, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n }\r\n\r\n private _createRetainedPartSource(proxy: GaussianSplattingPartProxyMesh): Nullable<IGaussianSplattingPartSource> {\r\n if (!this._splatsData || (this._shDegree > 0 && !this._shData)) {\r\n return null;\r\n }\r\n\r\n const splatByteOffset = proxy._splatsDataOffset * _GaussianSplattingBytesPerSplat;\r\n const splatByteLength = proxy._vertexCount * _GaussianSplattingBytesPerSplat;\r\n const shByteOffset = proxy._shDataOffset * _GaussianSplattingBytesPerShTexel;\r\n const shByteLength = proxy._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n\r\n return {\r\n name: proxy.name,\r\n _vertexCount: proxy._vertexCount,\r\n _splatsData: this._splatsData.slice(splatByteOffset, splatByteOffset + splatByteLength),\r\n _shData: this._shData?.map((texture) => texture.slice(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n _shDegree: this._shData?.length ?? 0,\r\n isCompound: false,\r\n getWorldMatrix: () => proxy.getWorldMatrix(),\r\n getBoundingInfo: () => proxy.getBoundingInfo(),\r\n dispose: () => {},\r\n };\r\n }\r\n\r\n private _retainMergedPartData(existingVertexCount: number, totalCount: number, others: IGaussianSplattingPartSource[], shDegree: number): void {\r\n if (!this._keepInRam && !this._alwaysRetainSplatsData) {\r\n this._splatsData = null;\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n const getSourceBuffer = (data: ArrayBuffer): ArrayBuffer => {\r\n return data instanceof ArrayBuffer ? data : ((data as unknown as ArrayBufferView).buffer as ArrayBuffer);\r\n };\r\n\r\n const mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n let splatByteOffset = 0;\r\n\r\n if (this._splatsData && existingVertexCount > 0) {\r\n mergedSplatsData.set(new Uint8Array(getSourceBuffer(this._splatsData), 0, existingVertexCount * _GaussianSplattingBytesPerSplat), splatByteOffset);\r\n splatByteOffset += existingVertexCount * _GaussianSplattingBytesPerSplat;\r\n }\r\n\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n continue;\r\n }\r\n\r\n const splatByteLength = other._vertexCount * _GaussianSplattingBytesPerSplat;\r\n mergedSplatsData.set(new Uint8Array(getSourceBuffer(other._splatsData), 0, splatByteLength), splatByteOffset);\r\n splatByteOffset += splatByteLength;\r\n }\r\n\r\n this._splatsData = mergedSplatsData.buffer;\r\n\r\n if (shDegree <= 0) {\r\n this._shData = null;\r\n return;\r\n }\r\n\r\n const mergedShData: Uint8Array[] = [];\r\n for (let textureIndex = 0; textureIndex < shDegree; textureIndex++) {\r\n mergedShData.push(new Uint8Array(totalCount * _GaussianSplattingBytesPerShTexel));\r\n }\r\n\r\n let shByteOffset = 0;\r\n if (this._shData && existingVertexCount > 0) {\r\n const existingShByteLength = existingVertexCount * _GaussianSplattingBytesPerShTexel;\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < this._shData.length) {\r\n mergedShData[textureIndex].set(this._shData[textureIndex].subarray(0, existingShByteLength), shByteOffset);\r\n }\r\n }\r\n shByteOffset += existingShByteLength;\r\n }\r\n\r\n for (const other of others) {\r\n const otherShByteLength = other._vertexCount * _GaussianSplattingBytesPerShTexel;\r\n if (other._shData) {\r\n for (let textureIndex = 0; textureIndex < mergedShData.length; textureIndex++) {\r\n if (textureIndex < other._shData.length) {\r\n mergedShData[textureIndex].set(other._shData[textureIndex].subarray(0, otherShByteLength), shByteOffset);\r\n }\r\n }\r\n }\r\n shByteOffset += otherShByteLength;\r\n }\r\n\r\n this._shData = mergedShData;\r\n }\r\n\r\n /**\r\n * Core implementation for adding one or more source parts as new\r\n * parts. Writes directly into texture-sized CPU arrays, updates the retained merged source\r\n * buffers, and uploads in one pass.\r\n *\r\n * @param others - Source meshes to append (must each be non-compound and fully loaded)\r\n * @param disposeOthers - Dispose source meshes after appending\r\n * @returns Proxy meshes and their assigned part indices\r\n */\r\n protected _addPartsInternal(others: IGaussianSplattingPartSource[], disposeOthers: boolean): { proxyMeshes: GaussianSplattingPartProxyMesh[]; assignedPartIndices: number[] } {\r\n if (others.length === 0) {\r\n return { proxyMeshes: [], assignedPartIndices: [] };\r\n }\r\n\r\n // Validate\r\n for (const other of others) {\r\n if (!other._splatsData) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must be fully loaded`);\r\n }\r\n if (other.isCompound) {\r\n throw new Error(`To call addPart()/addParts(), each source mesh must not be a compound`);\r\n }\r\n }\r\n\r\n const splatCountA = this._vertexCount;\r\n const totalOtherCount = others.reduce((s, o) => s + o._vertexCount, 0);\r\n const totalCount = splatCountA + totalOtherCount;\r\n\r\n const textureSize = this._getTextureSize(totalCount);\r\n const textureLength = textureSize.x * textureSize.y;\r\n const covBSItemSize = this._useRGBACovariants ? 4 : 2;\r\n\r\n // Allocate destination arrays for the full new texture\r\n const covA = new Uint16Array(textureLength * 4);\r\n const covB = new Uint16Array(covBSItemSize * textureLength);\r\n const colorArray = new Uint8Array(textureLength * 4);\r\n\r\n // Determine merged SH degree\r\n const hasSH = this._shData !== null && others.every((o) => o._shData !== null);\r\n const shDegreeNew = hasSH ? Math.max(this._shDegree, ...others.map((o) => o._shDegree)) : 0;\r\n let sh: Uint8Array[] | undefined = undefined;\r\n if (hasSH && shDegreeNew > 0) {\r\n const bytesPerTexel = 16;\r\n sh = [];\r\n for (let i = 0; i < shDegreeNew; i++) {\r\n sh.push(new Uint8Array(textureLength * bytesPerTexel));\r\n }\r\n }\r\n\r\n // --- Incremental path: can we reuse the already-committed GPU region? ---\r\n const incremental = this._canReuseCachedData(splatCountA, totalCount);\r\n const firstNewLine = incremental ? Math.floor(splatCountA / textureSize.x) : 0;\r\n\r\n const minimum = incremental ? this._cachedBoundingMin!.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const maximum = incremental ? this._cachedBoundingMax!.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Preserve existing processed positions in the new array\r\n const oldPositions = this._splatPositions;\r\n this._splatPositions = new Float32Array(4 * textureLength);\r\n if (incremental && oldPositions) {\r\n this._splatPositions.set(oldPositions.subarray(0, splatCountA * 4));\r\n }\r\n\r\n // --- Build part indices ---\r\n let nextPartIndex = this.partCount;\r\n let partIndicesA = this._partIndices;\r\n if (!partIndicesA) {\r\n // First addPart on a plain mesh: assign its splats to part 0\r\n partIndicesA = new Uint8Array(splatCountA);\r\n nextPartIndex = splatCountA > 0 ? 1 : 0;\r\n }\r\n\r\n this._partIndices = new Uint8Array(textureLength);\r\n this._partIndices.set(partIndicesA.subarray(0, splatCountA));\r\n\r\n const assignedPartIndices: number[] = [];\r\n const assignedSplatsDataOffsets: number[] = [];\r\n let dstOffset = splatCountA;\r\n const maxPartCount = GetGaussianSplattingMaxPartCount(this._scene.getEngine());\r\n for (const other of others) {\r\n if (nextPartIndex >= maxPartCount) {\r\n throw new Error(`Cannot add part, as the maximum part count (${maxPartCount}) has been reached`);\r\n }\r\n const newPartIndex = nextPartIndex++;\r\n assignedPartIndices.push(newPartIndex);\r\n assignedSplatsDataOffsets.push(dstOffset);\r\n this._partIndices.fill(newPartIndex, dstOffset, dstOffset + other._vertexCount);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // --- Process source data ---\r\n if (!incremental) {\r\n // Full rebuild path — only reached when the GPU texture must be reallocated\r\n // (either the texture height needs to grow to fit the new total, or this is\r\n // the very first addPart onto a mesh with no GPU textures yet). In the common\r\n // case where the texture height is unchanged, `incremental` is true and this\r\n // entire block is skipped. The `splatCountA > 0` guard avoids redundant work\r\n // on the first-ever addPart when the compound mesh starts empty.\r\n if (splatCountA > 0) {\r\n if (this._partProxies.length > 0) {\r\n // Already compound: rebuild every existing part from its stored source data.\r\n //\r\n // DESIGN NOTE: The intended use of GaussianSplattingMesh / GaussianSplattingCompoundMesh\r\n // in compound mode is to start EMPTY and compose parts exclusively via addPart/addParts.\r\n // In a future major version this will be the only supported path and the \"own data\"\r\n // legacy branch below will be removed.\r\n //\r\n // Until then, two layouts are possible:\r\n // A) LEGACY — compound loaded its own splat data (via URL or updateData) before\r\n // any addPart call. _partProxies[0] is undefined; the mesh's own splat data\r\n // is treated as an implicit \"part 0\" in this._splatsData. Proxied parts occupy\r\n // indices 1+. This layout will be deprecated in the next major version.\r\n // B) PREFERRED — compound started empty; first addPart assigned partIndex=0.\r\n // _partProxies[0] is set; this._splatsData is null; all parts are proxied.\r\n let rebuildOffset = 0;\r\n\r\n // Rebuild the compound's legacy \"own\" data at part 0 (scenario A only).\r\n // Skipped in the preferred empty-composer path (scenario B).\r\n if (!this._partProxies[0] && this._splatsData) {\r\n const proxyVertexCount = this._partProxies.reduce((sum, proxy) => sum + (proxy ? proxy._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyVertexCount;\r\n if (part0Count > 0) {\r\n const uBufA = new Uint8Array(this._splatsData);\r\n const fBufA = new Float32Array(this._splatsData);\r\n for (let i = 0; i < part0Count; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n const bytesPerTexel = 16;\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, part0Count * bytesPerTexel), 0);\r\n }\r\n }\r\n }\r\n rebuildOffset += part0Count;\r\n }\r\n }\r\n\r\n // Rebuild all proxied parts. Loop from index 0 because in the preferred\r\n // scenario B, part 0 is itself a proxied part with no implicit \"own\" data.\r\n for (let partIndex = 0; partIndex < this._partProxies.length; partIndex++) {\r\n const proxy = this._partProxies[partIndex];\r\n if (!proxy) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n this._appendPartSourceToArrays(source, rebuildOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n rebuildOffset += source._vertexCount;\r\n }\r\n } else {\r\n // No proxies yet: this is the very first addPart call on a mesh that loaded\r\n // its own splat data (scenario A legacy path). Re-process that own data so\r\n // it occupies the start of the new texture before the incoming part is appended.\r\n // In the preferred scenario B (empty composer) splatCountA is 0 and this\r\n // entire branch is skipped by the outer `if (splatCountA > 0)` guard.\r\n if (this._splatsData) {\r\n const uBufA = new Uint8Array(this._splatsData);\r\n const fBufA = new Float32Array(this._splatsData);\r\n for (let i = 0; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false);\r\n }\r\n if (sh && this._shData) {\r\n const bytesPerTexel = 16;\r\n for (let texIdx = 0; texIdx < sh.length; texIdx++) {\r\n if (texIdx < this._shData.length) {\r\n sh[texIdx].set(this._shData[texIdx].subarray(0, splatCountA * bytesPerTexel), 0);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Incremental path: rebuild the partial first row (indices firstNewTexel to splatCountA-1)\r\n // so _updateSubTextures does not upload stale zeros over those already-committed texels.\r\n // The base-class _updateData always re-processes from firstNewTexel for the same reason;\r\n // the compound path must do the same.\r\n if (incremental) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n if (this._partProxies.length === 0) {\r\n // No proxies: the mesh loaded its own splat data and this is the first\r\n // addPart call (scenario A legacy path). Re-process the partial boundary\r\n // row so it is not clobbered by stale zeros during the sub-texture upload.\r\n if (this._splatsData) {\r\n const uBufA = new Uint8Array(this._splatsData);\r\n const fBufA = new Float32Array(this._splatsData);\r\n for (let i = firstNewTexel; i < splatCountA; i++) {\r\n this._makeSplat(i, fBufA, uBufA, covA, covB, colorArray, minimum, maximum, false, i);\r\n }\r\n }\r\n } else {\r\n // Already compound: build a per-partIndex source lookup so each splat in the\r\n // partial boundary row can be re-processed from its original source buffer.\r\n //\r\n // Handles both layouts (see full-rebuild comment above):\r\n // A) LEGACY: _partProxies[0] absent → seed lookup[0] with this._splatsData\r\n // B) PREFERRED: _partProxies[0] present → all entries filled from proxies\r\n const proxyTotal = this._partProxies.reduce((s, p) => s + (p ? p._vertexCount : 0), 0);\r\n const part0Count = splatCountA - proxyTotal; // > 0 only in legacy scenario A\r\n const srcUBufs: (Uint8Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const srcFBufs: (Float32Array | null)[] = new Array(this._partProxies.length).fill(null);\r\n const partStarts: number[] = new Array(this._partProxies.length).fill(0);\r\n // Legacy scenario A: part 0 is the mesh's own loaded data.\r\n if (!this._partProxies[0] && this._splatsData && part0Count > 0) {\r\n srcUBufs[0] = new Uint8Array(this._splatsData);\r\n srcFBufs[0] = new Float32Array(this._splatsData);\r\n partStarts[0] = 0;\r\n }\r\n // All proxied parts — start from pi=0 to cover preferred scenario B.\r\n let cumOffset = part0Count;\r\n for (let pi = 0; pi < this._partProxies.length; pi++) {\r\n const proxy = this._partProxies[pi];\r\n if (!proxy) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source || !source._splatsData) {\r\n throw new Error(`Cannot rebuild compound part \"${proxy.name}\": the retained compound source data is not available.`);\r\n }\r\n srcUBufs[pi] = new Uint8Array(source._splatsData);\r\n srcFBufs[pi] = new Float32Array(source._splatsData);\r\n partStarts[pi] = cumOffset;\r\n cumOffset += source._vertexCount;\r\n }\r\n for (let splatIdx = firstNewTexel; splatIdx < splatCountA; splatIdx++) {\r\n const partIdx = this._partIndices ? this._partIndices[splatIdx] : 0;\r\n const uBuf = partIdx < srcUBufs.length ? srcUBufs[partIdx] : null;\r\n const fBuf = partIdx < srcFBufs.length ? srcFBufs[partIdx] : null;\r\n if (uBuf && fBuf) {\r\n this._makeSplat(splatIdx, fBuf, uBuf, covA, covB, colorArray, minimum, maximum, false, splatIdx - (partStarts[partIdx] ?? 0));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Append each new source\r\n dstOffset = splatCountA;\r\n for (const other of others) {\r\n this._appendPartSourceToArrays(other, dstOffset, covA, covB, colorArray, sh, minimum, maximum);\r\n dstOffset += other._vertexCount;\r\n }\r\n\r\n // Pad empty splats to texture boundary\r\n const paddedEnd = (totalCount + 15) & ~0xf;\r\n for (let i = totalCount; i < paddedEnd; i++) {\r\n this._makeEmptySplat(i, covA, covB, colorArray);\r\n }\r\n\r\n // --- Update vertex count / index buffer ---\r\n if (totalCount !== this._vertexCount) {\r\n this._updateSplatIndexBuffer(totalCount);\r\n }\r\n this._retainMergedPartData(splatCountA, totalCount, others, shDegreeNew);\r\n this._vertexCount = totalCount;\r\n this._shDegree = shDegreeNew;\r\n\r\n // Gate the sort worker for the duration of this operation. _updateTextures (below) may create the worker and fire an\r\n // immediate sort via _postToWorker. At that point partMatrices has not yet been updated for the incoming parts, so the\r\n // worker would compute depthCoeffs for fewer parts than partIndices references — crashing with\r\n // \"Cannot read properties of undefined (reading '0')\".\r\n // When called from removePart, _rebuilding is already true and _canPostToWorker is already false, so the gate is a\r\n // no-op — removePart handles the final post+sort.\r\n const needsWorkerGate = !this._rebuilding;\r\n if (needsWorkerGate) {\r\n this._canPostToWorker = false;\r\n this._rebuilding = true;\r\n }\r\n\r\n try {\r\n // --- Upload to GPU ---\r\n if (incremental) {\r\n // Update the part-indices texture (handles both create and update-in-place).\r\n // _ensurePartIndicesTexture is a no-op when the texture already exists, so on the\r\n // second+ addPart the partIndices would be stale without this call.\r\n this._onUpdateTextures(textureSize);\r\n this._updateSubTextures(this._splatPositions, covA, covB, colorArray, firstNewLine, textureSize.y - firstNewLine, sh);\r\n } else {\r\n this._updateTextures(covA, covB, colorArray, sh);\r\n }\r\n\r\n this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());\r\n this.setEnabled(true);\r\n this._cachedBoundingMin = minimum.clone();\r\n this._cachedBoundingMax = maximum.clone();\r\n this._notifyWorkerNewData();\r\n\r\n // --- Create proxy meshes ---\r\n const proxyMeshes: GaussianSplattingPartProxyMesh[] = [];\r\n for (let i = 0; i < others.length; i++) {\r\n const other = others[i];\r\n const newPartIndex = assignedPartIndices[i];\r\n\r\n const partWorldMatrix = other.getWorldMatrix();\r\n this.setWorldMatrixForPart(newPartIndex, partWorldMatrix);\r\n\r\n const proxyMesh = new GaussianSplattingPartProxyMesh(\r\n other.name,\r\n this.getScene(),\r\n this,\r\n newPartIndex,\r\n other.getBoundingInfo(),\r\n other._vertexCount,\r\n assignedSplatsDataOffsets[i],\r\n assignedSplatsDataOffsets[i]\r\n );\r\n\r\n if (disposeOthers) {\r\n other.dispose();\r\n }\r\n\r\n const quaternion = new Quaternion();\r\n partWorldMatrix.decompose(proxyMesh.scaling, quaternion, proxyMesh.position);\r\n proxyMesh.rotationQuaternion = quaternion;\r\n proxyMesh.computeWorldMatrix(true);\r\n\r\n this._partProxies[newPartIndex] = proxyMesh;\r\n proxyMeshes.push(proxyMesh);\r\n }\r\n\r\n // Restore the rebuild gate and post the now-complete partMatrices in one message, then trigger a single sort pass.\r\n // This ensures the worker sees a consistent partMatrices array that matches the partIndices for every splat.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n if (this._worker) {\r\n this._worker.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n }\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n }\r\n\r\n return { proxyMeshes, assignedPartIndices };\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n if (needsWorkerGate) {\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n }\r\n throw e;\r\n }\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Public compound API\r\n // ---------------------------------------------------------------------------\r\n\r\n /**\r\n * Add another mesh to this mesh, as a new part. This makes the current mesh a compound, if not already.\r\n * The source mesh's splat data is read directly and copied into the compound's retained source buffers.\r\n * @param other - The other mesh to add. Must be fully loaded before calling this method.\r\n * @param disposeOther - Whether to dispose the other mesh after adding it to the current mesh.\r\n * @returns a placeholder mesh that can be used to manipulate the part transform\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.addPart} instead.\r\n */\r\n public addPart(other: GaussianSplattingMesh, disposeOther: boolean = true): GaussianSplattingPartProxyMesh {\r\n const { proxyMeshes } = this._addPartsInternal([other], disposeOther);\r\n return proxyMeshes[0];\r\n }\r\n\r\n /**\r\n * Remove a part from this compound mesh.\r\n * The remaining parts are rebuilt directly from the compound mesh's retained source buffers.\r\n * The current mesh is reset to a plain (single-part) state and then each remaining source is\r\n * re-added via addParts.\r\n * @param index - The index of the part to remove\r\n * @deprecated Use {@link GaussianSplattingCompoundMesh.removePart} instead.\r\n */\r\n public removePart(index: number): void {\r\n if (index < 0 || index >= this.partCount) {\r\n throw new Error(`Part index ${index} is out of range [0, ${this.partCount})`);\r\n }\r\n\r\n // Collect surviving proxy objects (sorted by current part index so part 0 is added first)\r\n const survivors: Array<{ proxyMesh: GaussianSplattingPartProxyMesh; source: IGaussianSplattingPartSource; oldIndex: number; worldMatrix: Matrix; visibility: number }> = [];\r\n for (let proxyIndex = 0; proxyIndex < this._partProxies.length; proxyIndex++) {\r\n const proxy = this._partProxies[proxyIndex];\r\n if (!proxy || proxyIndex === index) {\r\n continue;\r\n }\r\n const source = this._createRetainedPartSource(proxy);\r\n if (!source) {\r\n throw new Error(`Cannot remove part: the retained compound source data is not available for part \"${proxy.name}\".`);\r\n }\r\n survivors.push({ proxyMesh: proxy, source, oldIndex: proxyIndex, worldMatrix: proxy.getWorldMatrix().clone(), visibility: this._partVisibility[proxyIndex] ?? 1.0 });\r\n }\r\n survivors.sort((a, b) => a.oldIndex - b.oldIndex);\r\n\r\n // Validate every survivor still has its source data. If even one is missing we cannot rebuild.\r\n for (const { proxyMesh, source } of survivors) {\r\n if (!source._splatsData) {\r\n throw new Error(`Cannot remove part: the source data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n if (source._shDegree > 0 && !source._shData) {\r\n throw new Error(`Cannot remove part: the SH data for part \"${proxyMesh.name}\" is not available.`);\r\n }\r\n }\r\n\r\n // --- Reset this mesh to an empty state ---\r\n // Terminate the sort worker before zeroing _vertexCount. The worker's onmessage handler\r\n // compares depthMix.length against (_vertexCount + 15) & ~0xf; with _vertexCount = 0 that\r\n // becomes 16, which causes a forced re-sort loop on stale data and resets _canPostToWorker\r\n // to true, defeating the gate below. The worker will be re-instantiated naturally after\r\n // the rebuild via the first _postToWorker call.\r\n if (this._worker) {\r\n this._worker.terminate();\r\n this._worker = null;\r\n }\r\n // Dispose and null GPU textures so _updateTextures sees firstTime=true and creates\r\n // fresh GPU textures.\r\n this._covariancesATexture?.dispose();\r\n this._covariancesBTexture?.dispose();\r\n this._centersTexture?.dispose();\r\n this._colorsTexture?.dispose();\r\n this._rotationsATexture?.dispose();\r\n this._rotationsBTexture?.dispose();\r\n this._rotationScaleTexture?.dispose();\r\n this._covariancesATexture = null;\r\n this._covariancesBTexture = null;\r\n this._centersTexture = null;\r\n this._colorsTexture = null;\r\n this._rotationsATexture = null;\r\n this._rotationsBTexture = null;\r\n this._rotationScaleTexture = null;\r\n if (this._shTextures) {\r\n for (const t of this._shTextures) {\r\n t.dispose();\r\n }\r\n this._shTextures = null;\r\n }\r\n if (this._partIndicesTexture) {\r\n this._partIndicesTexture.dispose();\r\n this._partIndicesTexture = null;\r\n }\r\n this._vertexCount = 0;\r\n this._splatPositions = null;\r\n this._partIndices = null;\r\n this._partMatrices = [];\r\n this._partVisibility = [];\r\n this._cachedBoundingMin = null;\r\n this._cachedBoundingMax = null;\r\n this._splatsData = null;\r\n this._shData = null;\r\n this._shDegree = 0;\r\n\r\n // Remove the proxy for the removed part and dispose it\r\n const proxyToRemove = this._partProxies[index];\r\n if (proxyToRemove) {\r\n proxyToRemove.dispose();\r\n }\r\n this._partProxies = [];\r\n\r\n // Rebuild from surviving sources. _addPartsInternal assigns part indices in order 0, 1, 2, …\r\n // so the new index for each survivor is simply its position in the survivors array.\r\n if (survivors.length === 0) {\r\n // Nothing left — leave the mesh empty.\r\n this.setEnabled(false);\r\n return;\r\n }\r\n\r\n // Gate the sort worker: suppress any sort request until the full rebuild is committed.\r\n this._rebuilding = true;\r\n this._canPostToWorker = false;\r\n try {\r\n const sources = survivors.map((s) => s.source);\r\n const { proxyMeshes: newProxies } = this._addPartsInternal(sources, false);\r\n\r\n // Restore world matrices and re-map proxies\r\n for (let i = 0; i < survivors.length; i++) {\r\n const oldProxy = survivors[i].proxyMesh;\r\n const newProxy = newProxies[i];\r\n const newPartIndex = newProxy.partIndex;\r\n\r\n // Restore the world matrix and visibility the user had set on the old proxy\r\n this.setWorldMatrixForPart(newPartIndex, survivors[i].worldMatrix);\r\n this.setPartVisibility(newPartIndex, survivors[i].visibility);\r\n const quaternion = new Quaternion();\r\n survivors[i].worldMatrix.decompose(newProxy.scaling, quaternion, newProxy.position);\r\n newProxy.rotationQuaternion = quaternion;\r\n newProxy.computeWorldMatrix(true);\r\n\r\n // Update the old proxy's index and metadata so existing user references still work.\r\n oldProxy.updatePartIndex(newPartIndex);\r\n oldProxy.updatePartMetadata(newProxy._vertexCount, newProxy._splatsDataOffset, newProxy._shDataOffset);\r\n this._partProxies[newPartIndex] = oldProxy;\r\n\r\n // newProxy is redundant — it was created inside _addPartsInternal; dispose it\r\n newProxy.dispose();\r\n }\r\n\r\n // Rebuild is complete: all partMatrices are now set correctly.\r\n // Post the final complete set and fire one sort.\r\n this._rebuilding = false;\r\n // Break TypeScript's flow narrowing — _addPartsInternal may have reinstantiated _worker.\r\n const workerAfterRebuild = this._worker as Worker | null;\r\n workerAfterRebuild?.postMessage({ partMatrices: this._partMatrices.map((matrix) => new Float32Array(matrix.m)) });\r\n this._canPostToWorker = true;\r\n this._postToWorker(true);\r\n } catch (e) {\r\n // Ensure the gates are always restored so sorting is not permanently frozen.\r\n this._rebuilding = false;\r\n this._canPostToWorker = true;\r\n throw e;\r\n }\r\n }\r\n\r\n /**\r\n * Serialize current GaussianSplattingMesh\r\n * @param serializationObject defines the object which will receive the serialization data\r\n * @param encoding the encoding of binary data, defaults to base64 for json serialize,\r\n * kept for future internal use like cloning where base64 encoding wastes cycles and memory\r\n * @returns the serialized object\r\n */\r\n public override serialize(serializationObject: any = {}, encoding: string = \"base64\"): any {\r\n serializationObject = super.serialize(serializationObject);\r\n serializationObject.subMeshes = [];\r\n serializationObject.geometryUniqueId = undefined;\r\n serializationObject.geometryId = undefined;\r\n serializationObject.materialUniqueId = undefined;\r\n serializationObject.materialId = undefined;\r\n serializationObject.instances = [];\r\n serializationObject.actions = undefined;\r\n serializationObject.type = this.getClassName();\r\n serializationObject.keepInRam = this._keepInRam;\r\n serializationObject.disableDepthSort = this._disableDepthSort;\r\n serializationObject.viewUpdateThreshold = this.viewUpdateThreshold;\r\n serializationObject._flipY = this._flipY;\r\n\r\n if (this._splatsData) {\r\n serializationObject.splatsData = encoding === \"base64\" ? EncodeArrayBufferToBase64(this._splatsData) : this._splatsData;\r\n }\r\n if (this._shData) {\r\n serializationObject.shData = encoding === \"base64\" ? this._shData.map(EncodeArrayBufferToBase64) : this._shData;\r\n }\r\n if (this._partIndices) {\r\n const compressedIndices = CompressPartIndices(this._partIndices.subarray(0, this._vertexCount));\r\n serializationObject.partIndices = encoding === \"base64\" ? EncodeArrayBufferToBase64(compressedIndices) : compressedIndices;\r\n }\r\n if (this._partProxies.length) {\r\n serializationObject.partProxies = this._partProxies.filter((proxy) => !!proxy).map((proxy) => proxy.serialize());\r\n }\r\n\r\n return serializationObject;\r\n }\r\n\r\n /**\r\n * Internal helper to parses a serialized GaussianSplattingMesh or GaussianSplattingCompoundMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh or GaussianSplattingCompoundMesh in\r\n * @param ctor the constructor of the mesh to create\r\n * @returns the created GaussianSplattingMesh\r\n * @internal\r\n */\r\n public static _ParseInternal<T extends GaussianSplattingMesh>(\r\n parsedMesh: any,\r\n scene: Scene,\r\n ctor: new (name: string, url: Nullable<string>, scene: Nullable<Scene>, keepInRam: boolean) => T\r\n ): T {\r\n const mesh = new ctor(parsedMesh.name, null, scene, parsedMesh.keepInRam);\r\n\r\n mesh.disableDepthSort = parsedMesh.disableDepthSort ?? false;\r\n mesh.viewUpdateThreshold = parsedMesh.viewUpdateThreshold ?? GaussianSplattingMeshBase._DefaultViewUpdateThreshold;\r\n\r\n let splatsData: ArrayBuffer | string | undefined = parsedMesh.splatsData;\r\n if (typeof splatsData === \"string\") {\r\n splatsData = DecodeBase64ToBinary(splatsData);\r\n }\r\n\r\n const shData: string[] | Uint8Array[] | undefined = parsedMesh.shData;\r\n let parsedShData: Uint8Array[] | undefined;\r\n if (Array.isArray(shData) && shData.length) {\r\n const newData: Uint8Array[] = [];\r\n for (let i = 0, length = shData.length; i < length; i++) {\r\n const data = shData[i];\r\n if (typeof data === \"string\") {\r\n newData[i] = new Uint8Array(DecodeBase64ToBinary(data));\r\n } else {\r\n newData[i] = data;\r\n }\r\n }\r\n parsedShData = newData;\r\n }\r\n\r\n let partIndices: string | Uint32Array | number[] | undefined = parsedMesh.partIndices;\r\n let parsedPartIndices: Uint8Array | undefined;\r\n if (typeof partIndices === \"string\") {\r\n partIndices = new Uint32Array(DecodeBase64ToBinary(partIndices));\r\n }\r\n if (partIndices) {\r\n parsedPartIndices = ParsePartIndices(partIndices);\r\n }\r\n\r\n if (splatsData) {\r\n const flipY = parsedMesh._flipY ?? false;\r\n mesh.updateData(splatsData, parsedShData, { flipY }, parsedPartIndices);\r\n }\r\n\r\n if (parsedMesh.partProxies) {\r\n for (const serializedPart of parsedMesh.partProxies) {\r\n const part = Object.assign({}, serializedPart);\r\n part.compoundSplatMesh = mesh;\r\n const proxyMesh = Mesh.Parse(part, scene, \"\") as GaussianSplattingPartProxyMesh;\r\n const newPartIndex = proxyMesh.partIndex;\r\n mesh._partProxies[newPartIndex] = proxyMesh;\r\n mesh.setWorldMatrixForPart(newPartIndex, proxyMesh.getWorldMatrix());\r\n mesh.setPartVisibility(newPartIndex, proxyMesh.visibility);\r\n }\r\n }\r\n\r\n return mesh;\r\n }\r\n\r\n /**\r\n * Parses a serialized GaussianSplattingMesh\r\n * @param parsedMesh the serialized mesh\r\n * @param scene the scene to create the GaussianSplattingMesh in\r\n * @returns the created GaussianSplattingMesh\r\n */\r\n public static override Parse(parsedMesh: any, scene: Scene): GaussianSplattingMesh {\r\n return GaussianSplattingMesh._ParseInternal(parsedMesh, scene, GaussianSplattingMesh);\r\n }\r\n}\r\n\r\nMesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n"]}
@@ -221,6 +221,8 @@ export declare class GaussianSplattingMeshBase extends Mesh {
221
221
  private _depthMix;
222
222
  protected _canPostToWorker: boolean;
223
223
  private _readyToDisplay;
224
+ private _sortRequestId;
225
+ private _hasRenderedOnce;
224
226
  protected _covariancesATexture: Nullable<BaseTexture>;
225
227
  protected _covariancesBTexture: Nullable<BaseTexture>;
226
228
  protected _centersTexture: Nullable<BaseTexture>;
@@ -392,6 +394,7 @@ export declare class GaussianSplattingMeshBase extends Mesh {
392
394
  */
393
395
  isReady(completeCheck?: boolean): boolean;
394
396
  _getCameraDirection(camera: Camera): Vector3;
397
+ private _isSortStateDirty;
395
398
  /** @internal */
396
399
  _postToWorker(forced?: boolean): void;
397
400
  /**