@babylonjs/core 9.10.0 → 9.10.1

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 (30) hide show
  1. package/DeviceInput/webDeviceInputSystem.js +7 -1
  2. package/DeviceInput/webDeviceInputSystem.js.map +1 -1
  3. package/Engines/abstractEngine.pure.js +2 -2
  4. package/Engines/abstractEngine.pure.js.map +1 -1
  5. package/Engines/engine.common.js +61 -1
  6. package/Engines/engine.common.js.map +1 -1
  7. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.d.ts +8 -0
  8. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js +26 -0
  9. package/Materials/GaussianSplatting/gaussianSplattingDebugMaterialPlugin.pure.js.map +1 -1
  10. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.d.ts +2 -0
  11. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js +17 -0
  12. package/Meshes/GaussianSplatting/gaussianSplattingDebugger.pure.js.map +1 -1
  13. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js +4 -0
  14. package/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.js.map +1 -1
  15. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.d.ts +6 -0
  16. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js +8 -0
  17. package/Meshes/GaussianSplatting/gaussianSplattingMeshBase.pure.js.map +1 -1
  18. package/Misc/tools.pure.js +1 -1
  19. package/Misc/tools.pure.js.map +1 -1
  20. package/SmartAssets/index.d.ts +1 -1
  21. package/SmartAssets/index.js +1 -1
  22. package/SmartAssets/index.js.map +1 -1
  23. package/SmartAssets/pure.d.ts +1 -0
  24. package/SmartAssets/pure.js +1 -0
  25. package/SmartAssets/pure.js.map +1 -1
  26. package/SmartAssets/{smartAssetManager.js → smartAssetManager.pure.js} +30 -17
  27. package/SmartAssets/smartAssetManager.pure.js.map +1 -0
  28. package/package.json +1 -1
  29. package/SmartAssets/smartAssetManager.js.map +0 -1
  30. /package/SmartAssets/{smartAssetManager.d.ts → smartAssetManager.pure.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"gaussianSplattingMesh.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Vector2 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { GaussianSplattingMeshBase, AllocateShBuffers } from \"./gaussianSplattingMeshBase.pure\";\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.pure\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\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 | ArrayBufferView>;\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 /** Part 0 local-space AABB when owned directly (not proxied). Set on first addPart, cleared on dispose/reset. */\r\n private _part0LocalMin: Nullable<Vector3> = null;\r\n private _part0LocalMax: Nullable<Vector3> = null;\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 * Recomputes compound local-space bounds from part 0's stored AABB (if unproxied) plus all\r\n * proxy world AABBs inverse-transformed to compound-local space. All 8 corners of each proxy\r\n * AABB are transformed so the result is correct under non-identity compound rotation/scale.\r\n */\r\n private _updateBoundingInfoFromProxies(): void {\r\n const compoundWorld = this.getWorldMatrix();\r\n const invCompoundWorld = Matrix.Invert(compoundWorld);\r\n\r\n const localMin = this._part0LocalMin ? this._part0LocalMin.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const localMax = this._part0LocalMax ? this._part0LocalMax.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n const corner = new Vector3();\r\n for (const proxy of this._partProxies) {\r\n if (!proxy) {\r\n continue;\r\n }\r\n // Proxies have no geometry — getHierarchyBoundingVectors returns sentinels. Use boundingBox directly.\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n const wMin = bb.minimumWorld;\r\n const wMax = bb.maximumWorld;\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? wMax.x : wMin.x, b & 2 ? wMax.y : wMin.y, b & 4 ? wMax.z : wMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, invCompoundWorld, corner);\r\n localMin.minimizeInPlace(corner);\r\n localMax.maximizeInPlace(corner);\r\n }\r\n }\r\n\r\n if (localMin.x <= localMax.x) {\r\n // Direct access avoids getBoundingInfo() → _updateBoundingInfo() recursion.\r\n if (this._boundingInfo) {\r\n this._boundingInfo.reConstruct(localMin, localMax, compoundWorld);\r\n } else {\r\n this._boundingInfo = new BoundingInfo(localMin, localMax, compoundWorld);\r\n }\r\n this._cachedBoundingMin = localMin.clone();\r\n this._cachedBoundingMax = localMax.clone();\r\n }\r\n }\r\n\r\n /**\r\n * Override for compound meshes: recomputes bounds from proxy world extents instead of\r\n * local bounds × world matrix, which is wrong for proxied parts with independent transforms.\r\n * @returns this mesh\r\n */\r\n public override _updateBoundingInfo(): AbstractMesh {\r\n if (this.isCompound) {\r\n this._updateBoundingInfoFromProxies();\r\n this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n return this;\r\n }\r\n return super._updateBoundingInfo();\r\n }\r\n\r\n /**\r\n * Replaces the base hierarchy bounds computation for compound meshes: computes world bounds\r\n * from scratch by iterating part 0's local AABB and all proxy meshes, rather than delegating\r\n * to the base _children traversal which never reaches proxies (they are not parented to the\r\n * compound). Visibility per-part is respected; invisible parts are excluded.\r\n * @param includeDescendants when true, includes descendants (default: true)\r\n * @param predicate optional filter predicate\r\n * @returns world-space min/max of the hierarchy bounding box\r\n */\r\n public override getHierarchyBoundingVectors(\r\n includeDescendants: boolean = true,\r\n predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n ): { min: Vector3; max: Vector3 } {\r\n if (!this.isCompound) {\r\n return super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n }\r\n // For compound meshes, compute visible-only world bounds from scratch so that\r\n // invisible parts don't inflate the result (e.g. for voxelization scene bounds).\r\n const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n // Unproxied part 0: the compound mesh owns this geometry directly (no proxy node).\r\n // Transform its local AABB to world space if visible.\r\n if (this._part0LocalMin && (this._partVisibility[0] ?? 1.0) > 0) {\r\n const wm = this.getWorldMatrix();\r\n const lMin = this._part0LocalMin;\r\n const lMax = this._part0LocalMax!;\r\n const corner = new Vector3();\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? lMax.x : lMin.x, b & 2 ? lMax.y : lMin.y, b & 4 ? lMax.z : lMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, wm, corner);\r\n min.minimizeInPlace(corner);\r\n max.maximizeInPlace(corner);\r\n }\r\n }\r\n for (let i = 0; i < this._partProxies.length; i++) {\r\n const proxy = this._partProxies[i];\r\n if (!proxy || (this._partVisibility[i] ?? 1.0) === 0) {\r\n continue;\r\n }\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n min.minimizeInPlace(bb.minimumWorld);\r\n max.maximizeInPlace(bb.maximumWorld);\r\n }\r\n return { min, max };\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 this._part0LocalMin = null;\r\n this._part0LocalMax = 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 const splatBytes = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n\r\n return {\r\n name: proxy.name,\r\n _vertexCount: proxy._vertexCount,\r\n _splatsData: splatBytes.subarray(splatByteOffset, splatByteOffset + splatByteLength),\r\n _shData: this._shData?.map((texture) => texture.subarray(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n _shDegree: this._shData ? this._shDegree : 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 mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n let splatByteOffset = 0;\r\n\r\n if (this._splatsData && existingVertexCount > 0) {\r\n mergedSplatsData.set(\r\n GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData).subarray(0, existingVertexCount * _GaussianSplattingBytesPerSplat),\r\n splatByteOffset\r\n );\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(GaussianSplattingMeshBase._GetSplatDataBytes(other._splatsData).subarray(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 // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n const mergedShData = AllocateShBuffers(shTextureCount, totalCount * _GaussianSplattingBytesPerShTexel);\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 // hasSH is true when the merged result will carry SH:\r\n // - Existing compound already has SH (_shDegree>0): preserve it even if new parts\r\n // have no SH — their texel region is pre-filled with 128 (neutral) by AllocateShBuffers.\r\n // - At least one new part carries SH: enable SH for the whole compound; existing\r\n // parts that had no SH also get neutral fill.\r\n // Deliberately excludes the case where the existing compound has no SH and no new part\r\n // has SH either (shDegreeNew stays 0, no SH textures allocated).\r\n const hasSH = this._shDegree > 0 || others.some((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 // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegreeNew + 1) * (shDegreeNew + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n sh = AllocateShBuffers(shTextureCount, textureLength * _GaussianSplattingBytesPerShTexel);\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 = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(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 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 * _GaussianSplattingBytesPerShTexel), 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 = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(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 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 * _GaussianSplattingBytesPerShTexel), 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 // Boundary-row SH is restored after _retainMergedPartData (see below), where _shData is ready.\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 = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(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] = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n srcFBufs[0] = GaussianSplattingMeshBase._GetSplatDataFloats(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] = GaussianSplattingMeshBase._GetSplatDataBytes(source._splatsData);\r\n srcFBufs[pi] = GaussianSplattingMeshBase._GetSplatDataFloats(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 // Create missing SH GPU textures: either the compound just gained SH for the first\r\n // time (_shTextures===null) or the degree increased (sh.length > _shTextures.length).\r\n // Use _shData when available (contains correct merged values for all rows);\r\n // fall back to sh[idx] (pre-filled with 128) when _shData is absent (keepInRam=false).\r\n // _updateSubTextures will re-upload from firstNewLine, which is redundant but harmless.\r\n if (sh && (!this._shTextures || sh.length > this._shTextures.length)) {\r\n if (!this._shTextures) {\r\n this._shTextures = [];\r\n }\r\n while (this._shTextures.length < sh.length) {\r\n const idx = this._shTextures.length;\r\n const shTexture = new RawTexture(\r\n null,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RGBA_INTEGER,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_INTEGER\r\n );\r\n shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._shTextures.push(shTexture);\r\n const src = this._shData && idx < this._shData.length ? this._shData[idx] : sh[idx];\r\n this._updateShTextureData(shTexture, src, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n\r\n // Restore boundary-row SH: sh is freshly filled with 128, and _updateSubTextures\r\n // starts at firstNewLine — existing splats on that row need their values from _shData.\r\n if (sh && this._shData) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n const byteStart = firstNewTexel * _GaussianSplattingBytesPerShTexel;\r\n const byteEnd = splatCountA * _GaussianSplattingBytesPerShTexel;\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(byteStart, byteEnd), byteStart);\r\n }\r\n }\r\n }\r\n }\r\n\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.setEnabled(true);\r\n this._notifyWorkerNewData();\r\n\r\n // Bounding info is updated via _updateBoundingInfoFromProxies (called below, after proxy\r\n // world matrices are known), which needs part 0's local-space AABB as an input:\r\n // • For unproxied part 0 (legacy layout A: compound loaded its own splat data before\r\n // any addPart call, so no _partProxies[0]), capture the local-space AABB from the\r\n // compound mesh's existing _boundingInfo — set when the mesh loaded its own data via\r\n // URL/updateData — so _updateBoundingInfoFromProxies can include part 0's geometry.\r\n // • For proxied part 0, skip — its bounds are already on the proxy's getBoundingInfo()\r\n // and _updateBoundingInfoFromProxies picks it up there.\r\n // Guard splatCountA > 0 avoids reading a stale bounding box on a fresh empty mesh.\r\n // Guard !this._part0LocalMin ensures we only store once; subsequent addPart calls must\r\n // not overwrite it, because by then _boundingInfo reflects the full merged dataset.\r\n if (!this._partProxies[0] && splatCountA > 0 && !this._part0LocalMin) {\r\n this._part0LocalMin = this.getBoundingInfo().minimum.clone();\r\n this._part0LocalMax = this.getBoundingInfo().maximum.clone();\r\n }\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 // Update compound bounds now that all proxy world matrices are known.\r\n this._updateBoundingInfoFromProxies();\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._part0LocalMin = null;\r\n this._part0LocalMax = 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 serializationObject.shDegree = this._shDegree;\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, parsedMesh.shDegree);\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\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingMesh(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n Mesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n}\r\n"]}
1
+ {"version":3,"file":"gaussianSplattingMesh.pure.js","sourceRoot":"","sources":["../../../../../dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts"],"names":[],"mappings":"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","sourcesContent":["/** This file must only contain pure code and pure imports */\r\n\r\nimport { type Nullable } from \"core/types\";\r\nimport { type Scene } from \"core/scene.pure\";\r\nimport { Matrix, Quaternion, Vector3 } from \"core/Maths/math.vector.pure\";\r\nimport { type Vector2 } from \"core/Maths/math.vector\";\r\nimport { type Effect } from \"core/Materials/effect.pure\";\r\nimport { GetGaussianSplattingMaxPartCount } from \"core/Materials/GaussianSplatting/gaussianSplattingMaterial.pure\";\r\nimport { GaussianSplattingMeshBase, AllocateShBuffers } from \"./gaussianSplattingMeshBase.pure\";\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.pure\";\r\nimport { GaussianSplattingPartProxyMesh } from \"./gaussianSplattingPartProxyMesh.pure\";\r\nimport { BoundingInfo } from \"../../Culling/boundingInfo\";\r\nimport { type BaseTexture } from \"../../Materials/Textures/baseTexture.pure\";\r\nimport { type AbstractMesh } from \"core/Meshes/abstractMesh.pure\";\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 | ArrayBufferView>;\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 /** Part 0 local-space AABB when owned directly (not proxied). Set on first addPart, cleared on dispose/reset. */\r\n private _part0LocalMin: Nullable<Vector3> = null;\r\n private _part0LocalMax: Nullable<Vector3> = null;\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 * Recomputes compound local-space bounds from part 0's stored AABB (if unproxied) plus all\r\n * proxy world AABBs inverse-transformed to compound-local space. All 8 corners of each proxy\r\n * AABB are transformed so the result is correct under non-identity compound rotation/scale.\r\n */\r\n private _updateBoundingInfoFromProxies(): void {\r\n const compoundWorld = this.getWorldMatrix();\r\n const invCompoundWorld = Matrix.Invert(compoundWorld);\r\n\r\n const localMin = this._part0LocalMin ? this._part0LocalMin.clone() : new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const localMax = this._part0LocalMax ? this._part0LocalMax.clone() : new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n const corner = new Vector3();\r\n for (const proxy of this._partProxies) {\r\n if (!proxy) {\r\n continue;\r\n }\r\n // Proxies have no geometry — getHierarchyBoundingVectors returns sentinels. Use boundingBox directly.\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n const wMin = bb.minimumWorld;\r\n const wMax = bb.maximumWorld;\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? wMax.x : wMin.x, b & 2 ? wMax.y : wMin.y, b & 4 ? wMax.z : wMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, invCompoundWorld, corner);\r\n localMin.minimizeInPlace(corner);\r\n localMax.maximizeInPlace(corner);\r\n }\r\n }\r\n\r\n if (localMin.x <= localMax.x) {\r\n // Direct access avoids getBoundingInfo() → _updateBoundingInfo() recursion.\r\n if (this._boundingInfo) {\r\n this._boundingInfo.reConstruct(localMin, localMax, compoundWorld);\r\n } else {\r\n this._boundingInfo = new BoundingInfo(localMin, localMax, compoundWorld);\r\n }\r\n this._cachedBoundingMin = localMin.clone();\r\n this._cachedBoundingMax = localMax.clone();\r\n }\r\n }\r\n\r\n /**\r\n * Override for compound meshes: recomputes bounds from proxy world extents instead of\r\n * local bounds × world matrix, which is wrong for proxied parts with independent transforms.\r\n * @returns this mesh\r\n */\r\n public override _updateBoundingInfo(): AbstractMesh {\r\n if (this.isCompound) {\r\n this._updateBoundingInfoFromProxies();\r\n this._updateSubMeshesBoundingInfo(this.worldMatrixFromCache);\r\n return this;\r\n }\r\n return super._updateBoundingInfo();\r\n }\r\n\r\n /**\r\n * Replaces the base hierarchy bounds computation for compound meshes: computes world bounds\r\n * from scratch by iterating part 0's local AABB and all proxy meshes, rather than delegating\r\n * to the base _children traversal which never reaches proxies (they are not parented to the\r\n * compound). Visibility per-part is respected; invisible parts are excluded.\r\n * @param includeDescendants when true, includes descendants (default: true)\r\n * @param predicate optional filter predicate\r\n * @returns world-space min/max of the hierarchy bounding box\r\n */\r\n public override getHierarchyBoundingVectors(\r\n includeDescendants: boolean = true,\r\n predicate: Nullable<(abstractMesh: AbstractMesh) => boolean> = null\r\n ): { min: Vector3; max: Vector3 } {\r\n if (!this.isCompound) {\r\n return super.getHierarchyBoundingVectors(includeDescendants, predicate);\r\n }\r\n // For compound meshes, compute visible-only world bounds from scratch so that\r\n // invisible parts don't inflate the result (e.g. for voxelization scene bounds).\r\n const min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n const max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n // Unproxied part 0: the compound mesh owns this geometry directly (no proxy node).\r\n // Transform its local AABB to world space if visible.\r\n if (this._part0LocalMin && (this._partVisibility[0] ?? 1.0) > 0) {\r\n const wm = this.getWorldMatrix();\r\n const lMin = this._part0LocalMin;\r\n const lMax = this._part0LocalMax!;\r\n const corner = new Vector3();\r\n for (let b = 0; b < 8; b++) {\r\n corner.set(b & 1 ? lMax.x : lMin.x, b & 2 ? lMax.y : lMin.y, b & 4 ? lMax.z : lMin.z);\r\n Vector3.TransformCoordinatesToRef(corner, wm, corner);\r\n min.minimizeInPlace(corner);\r\n max.maximizeInPlace(corner);\r\n }\r\n }\r\n for (let i = 0; i < this._partProxies.length; i++) {\r\n const proxy = this._partProxies[i];\r\n if (!proxy || (this._partVisibility[i] ?? 1.0) === 0) {\r\n continue;\r\n }\r\n proxy.computeWorldMatrix(false);\r\n const bb = proxy.getBoundingInfo().boundingBox;\r\n min.minimizeInPlace(bb.minimumWorld);\r\n max.maximizeInPlace(bb.maximumWorld);\r\n }\r\n return { min, max };\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 this._part0LocalMin = null;\r\n this._part0LocalMax = 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 const splatBytes = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n\r\n return {\r\n name: proxy.name,\r\n _vertexCount: proxy._vertexCount,\r\n _splatsData: splatBytes.subarray(splatByteOffset, splatByteOffset + splatByteLength),\r\n _shData: this._shData?.map((texture) => texture.subarray(shByteOffset, shByteOffset + shByteLength)) ?? null,\r\n _shDegree: this._shData ? this._shDegree : 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 mergedSplatsData = new Uint8Array(totalCount * _GaussianSplattingBytesPerSplat);\r\n let splatByteOffset = 0;\r\n\r\n if (this._splatsData && existingVertexCount > 0) {\r\n mergedSplatsData.set(\r\n GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData).subarray(0, existingVertexCount * _GaussianSplattingBytesPerSplat),\r\n splatByteOffset\r\n );\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(GaussianSplattingMeshBase._GetSplatDataBytes(other._splatsData).subarray(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 // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegree + 1) * (shDegree + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n const mergedShData = AllocateShBuffers(shTextureCount, totalCount * _GaussianSplattingBytesPerShTexel);\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 // hasSH is true when the merged result will carry SH:\r\n // - Existing compound already has SH (_shDegree>0): preserve it even if new parts\r\n // have no SH — their texel region is pre-filled with 128 (neutral) by AllocateShBuffers.\r\n // - At least one new part carries SH: enable SH for the whole compound; existing\r\n // parts that had no SH also get neutral fill.\r\n // Deliberately excludes the case where the existing compound has no SH and no new part\r\n // has SH either (shDegreeNew stays 0, no SH textures allocated).\r\n const hasSH = this._shDegree > 0 || others.some((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 // Each SH texture holds one texel per splat; each texel is _GaussianSplattingBytesPerShTexel\r\n // bytes with one byte per scalar, so it carries that many scalars. Degree d has\r\n // ((d+1)^2 - 1) higher-order coefficients × 3 RGB = total scalars per splat; divide by texel capacity.\r\n const shTextureCount = Math.ceil((((shDegreeNew + 1) * (shDegreeNew + 1) - 1) * 3) / _GaussianSplattingBytesPerShTexel);\r\n sh = AllocateShBuffers(shTextureCount, textureLength * _GaussianSplattingBytesPerShTexel);\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 = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(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 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 * _GaussianSplattingBytesPerShTexel), 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 = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(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 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 * _GaussianSplattingBytesPerShTexel), 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 // Boundary-row SH is restored after _retainMergedPartData (see below), where _shData is ready.\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 = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n const fBufA = GaussianSplattingMeshBase._GetSplatDataFloats(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] = GaussianSplattingMeshBase._GetSplatDataBytes(this._splatsData);\r\n srcFBufs[0] = GaussianSplattingMeshBase._GetSplatDataFloats(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] = GaussianSplattingMeshBase._GetSplatDataBytes(source._splatsData);\r\n srcFBufs[pi] = GaussianSplattingMeshBase._GetSplatDataFloats(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 // Create missing SH GPU textures: either the compound just gained SH for the first\r\n // time (_shTextures===null) or the degree increased (sh.length > _shTextures.length).\r\n // Use _shData when available (contains correct merged values for all rows);\r\n // fall back to sh[idx] (pre-filled with 128) when _shData is absent (keepInRam=false).\r\n // _updateSubTextures will re-upload from firstNewLine, which is redundant but harmless.\r\n if (sh && (!this._shTextures || sh.length > this._shTextures.length)) {\r\n if (!this._shTextures) {\r\n this._shTextures = [];\r\n }\r\n while (this._shTextures.length < sh.length) {\r\n const idx = this._shTextures.length;\r\n const shTexture = new RawTexture(\r\n null,\r\n textureSize.x,\r\n textureSize.y,\r\n Constants.TEXTUREFORMAT_RGBA_INTEGER,\r\n this._scene,\r\n false,\r\n false,\r\n Constants.TEXTURE_NEAREST_SAMPLINGMODE,\r\n Constants.TEXTURETYPE_UNSIGNED_INTEGER\r\n );\r\n shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;\r\n this._shTextures.push(shTexture);\r\n const src = this._shData && idx < this._shData.length ? this._shData[idx] : sh[idx];\r\n this._updateShTextureData(shTexture, src, textureSize.x, 0, textureSize.y);\r\n }\r\n }\r\n\r\n // Restore boundary-row SH: sh is freshly filled with 128, and _updateSubTextures\r\n // starts at firstNewLine — existing splats on that row need their values from _shData.\r\n if (sh && this._shData) {\r\n const firstNewTexel = firstNewLine * textureSize.x;\r\n if (firstNewTexel < splatCountA) {\r\n const byteStart = firstNewTexel * _GaussianSplattingBytesPerShTexel;\r\n const byteEnd = splatCountA * _GaussianSplattingBytesPerShTexel;\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(byteStart, byteEnd), byteStart);\r\n }\r\n }\r\n }\r\n }\r\n\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.setEnabled(true);\r\n this._notifyWorkerNewData();\r\n\r\n // Bounding info is updated via _updateBoundingInfoFromProxies (called below, after proxy\r\n // world matrices are known), which needs part 0's local-space AABB as an input:\r\n // • For unproxied part 0 (legacy layout A: compound loaded its own splat data before\r\n // any addPart call, so no _partProxies[0]), capture the local-space AABB from the\r\n // compound mesh's existing _boundingInfo — set when the mesh loaded its own data via\r\n // URL/updateData — so _updateBoundingInfoFromProxies can include part 0's geometry.\r\n // • For proxied part 0, skip — its bounds are already on the proxy's getBoundingInfo()\r\n // and _updateBoundingInfoFromProxies picks it up there.\r\n // Guard splatCountA > 0 avoids reading a stale bounding box on a fresh empty mesh.\r\n // Guard !this._part0LocalMin ensures we only store once; subsequent addPart calls must\r\n // not overwrite it, because by then _boundingInfo reflects the full merged dataset.\r\n if (!this._partProxies[0] && splatCountA > 0 && !this._part0LocalMin) {\r\n this._part0LocalMin = this.getBoundingInfo().minimum.clone();\r\n this._part0LocalMax = this.getBoundingInfo().maximum.clone();\r\n }\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 // Update compound bounds now that all proxy world matrices are known.\r\n this._updateBoundingInfoFromProxies();\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 this.onPartCountChangedObservable.notifyObservers(this.partCount);\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 // Notify listeners before mutation so they can record state keyed on the original index.\r\n this.onPartRemovedObservable.notifyObservers(index);\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._part0LocalMin = null;\r\n this._part0LocalMax = 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 this.onPartCountChangedObservable.notifyObservers(0);\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 serializationObject.shDegree = this._shDegree;\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, parsedMesh.shDegree);\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\nlet _Registered = false;\r\n/**\r\n * Register side effects for gaussianSplattingMesh.\r\n * Safe to call multiple times; only the first call has an effect.\r\n */\r\nexport function RegisterGaussianSplattingMesh(): void {\r\n if (_Registered) {\r\n return;\r\n }\r\n _Registered = true;\r\n\r\n Mesh._GaussianSplattingMeshParser = GaussianSplattingMesh.Parse;\r\n}\r\n"]}
@@ -6,6 +6,7 @@ import { SubMesh } from "../subMesh.pure.js";
6
6
  import { type AbstractMesh } from "../abstractMesh.pure.js";
7
7
  import { Mesh } from "../mesh.pure.js";
8
8
  import { Matrix, Vector2, Vector3 } from "../../Maths/math.vector.pure.js";
9
+ import { Observable } from "../../Misc/observable.js";
9
10
  import { type InternalTexture } from "../../Materials/Textures/internalTexture.js";
10
11
  import { type Material } from "../../Materials/material.pure.js";
11
12
  import { type Effect } from "../../Materials/effect.pure.js";
@@ -297,6 +298,11 @@ export declare class GaussianSplattingMeshBase extends Mesh {
297
298
  private static readonly _BatchSize;
298
299
  private _cameraViewInfos;
299
300
  protected static readonly _DefaultViewUpdateThreshold = 0.0001;
301
+ /** Fired after parts are added or the mesh is rebuilt following a removal. Payload is the new part count. */
302
+ readonly onPartCountChangedObservable: Observable<number>;
303
+ /** Fired after part-removal validation passes but before the mesh is rebuilt.
304
+ * Payload is the original (pre-removal) part index. */
305
+ readonly onPartRemovedObservable: Observable<number>;
300
306
  /**
301
307
  * Returns a byte-accurate view for retained splat data, preserving any non-zero byte offset.
302
308
  * @param data The retained splat source bytes.
@@ -4,6 +4,7 @@ import { Mesh } from "../mesh.pure.js";
4
4
  import { VertexData } from "../mesh.vertexData.js";
5
5
  import { Matrix, TmpVectors, Vector2, Vector3 } from "../../Maths/math.vector.pure.js";
6
6
  import { Logger } from "../../Misc/logger.js";
7
+ import { Observable } from "../../Misc/observable.js";
7
8
  import { GaussianSplattingMaterial } from "../../Materials/GaussianSplatting/gaussianSplattingMaterial.pure.js";
8
9
  import { RawTexture } from "../../Materials/Textures/rawTexture.js";
9
10
 
@@ -562,6 +563,11 @@ export class GaussianSplattingMeshBase extends Mesh {
562
563
  this._shDegree = 0;
563
564
  this._maxShDegree = 0;
564
565
  this._cameraViewInfos = new Map();
566
+ /** Fired after parts are added or the mesh is rebuilt following a removal. Payload is the new part count. */
567
+ this.onPartCountChangedObservable = new Observable();
568
+ /** Fired after part-removal validation passes but before the mesh is rebuilt.
569
+ * Payload is the original (pre-removal) part index. */
570
+ this.onPartRemovedObservable = new Observable();
565
571
  /**
566
572
  * Cosine value of the angle threshold to update view dependent splat sorting. Default is 0.0001.
567
573
  */
@@ -1683,6 +1689,8 @@ export class GaussianSplattingMeshBase extends Mesh {
1683
1689
  // this mesh's data before disposal.
1684
1690
  this._worker?.terminate();
1685
1691
  this._worker = null;
1692
+ this.onPartCountChangedObservable.clear();
1693
+ this.onPartRemovedObservable.clear();
1686
1694
  // delete meshes created for each camera
1687
1695
  this._cameraViewInfos.forEach((cameraViewInfo) => {
1688
1696
  cameraViewInfo.mesh.dispose();