import { type Nullable } from "../../types.js";
import { type Scene } from "../../scene.js";
import { type Matrix, type Vector2 } from "../../Maths/math.vector.js";
import { type Effect } from "../../Materials/effect.js";
import { GaussianSplattingMeshBase } from "./gaussianSplattingMeshBase.js";
import "../thinInstanceMesh.js";
import { GaussianSplattingPartProxyMesh } from "./gaussianSplattingPartProxyMesh.js";
/**
 * Class used to render a Gaussian Splatting mesh. Supports both single-cloud and compound
 * (multi-part) rendering. In compound mode, multiple Gaussian Splatting source meshes are
 * merged into one draw call while retaining per-part world-matrix control via
 * addPart/addParts and removePart.
 */
export declare class GaussianSplattingMesh extends GaussianSplattingMeshBase {
    /**
     * Proxy meshes indexed by part index. Maintained in sync with _partMatrices.
     */
    private _partProxies;
    /**
     * World matrices for each part, indexed by part index.
     */
    protected _partMatrices: Matrix[];
    /** When true, suppresses the sort trigger inside setWorldMatrixForPart during batch rebuilds. */
    private _rebuilding;
    /**
     * Visibility values for each part (0.0 to 1.0), indexed by part index.
     */
    protected _partVisibility: number[];
    private _partIndicesTexture;
    private _partIndices;
    /**
     * Creates a new GaussianSplattingMesh
     * @param name the name of the mesh
     * @param url optional URL to load a Gaussian Splatting file from
     * @param scene the hosting scene
     * @param keepInRam whether to keep the raw splat data in RAM after uploading to GPU
     */
    constructor(name: string, url?: Nullable<string>, scene?: Nullable<Scene>, keepInRam?: boolean);
    /**
     * Returns the class name
     * @returns "GaussianSplattingMesh"
     */
    getClassName(): string;
    /**
     * Disposes proxy meshes and clears part data in addition to the base class GPU resources.
     * @param doNotRecurse Set to true to not recurse into each children
     */
    dispose(doNotRecurse?: boolean): void;
    /**
     * Posts the initial per-part data to the sort worker after it has been created.
     * Sends the current part matrices and group index array so the worker can correctly
     * weight depth values per part.
     * @param worker the newly created sort worker
     */
    protected _onWorkerCreated(worker: Worker): void;
    /**
     * Stores the raw part index array, padded to texture length, so the worker and GPU texture
     * creation step have access to it.
     * @param partIndices - the raw part indices array received during a data load
     * @param textureLength - the padded texture length to allocate into
     */
    protected _onIndexDataReceived(partIndices: Uint8Array, textureLength: number): void;
    /**
     * Returns `true` when at least one part has been added to this compound mesh.
     * Returns `false` before any parts are added, so the mesh renders in normal
     * (non-compound) mode until the first addPart/addParts call. This matches the
     * old base-class behavior of `this._partMatrices.length > 0` and avoids
     * binding unset partWorld uniforms (which would cause division-by-zero in the
     * Gaussian projection Jacobian and produce huge distorted splats).
     * @internal
     */
    get isCompound(): boolean;
    /**
     * During a removePart rebuild, keep the existing sort worker alive rather than
     * tearing it down and spinning up a new one. This avoids startup latency and the
     * transient state window where a stale sort could fire against an incomplete
     * partMatrices array.
     * Outside of a rebuild the base-class behaviour is used unchanged.
     */
    protected _instantiateWorker(): void;
    /**
     * Ensures the part-index GPU texture exists at the start of an incremental update.
     * Called before the sub-texture upload so the correct texture is available for the first batch.
     * @param textureSize - current texture dimensions
     */
    protected _onIncrementalUpdateStart(textureSize: Vector2): void;
    /**
     * Posts positions (via super) and then additionally posts the current part-index array
     * to the sort worker so it can associate each splat with its part.
     */
    protected _notifyWorkerNewData(): void;
    /**
     * Binds all compound-specific shader uniforms: the group index texture, per-part world
     * matrices, and per-part visibility values.
     * @param effect the shader effect that is being bound
     * @internal
     */
    bindExtraEffectUniforms(effect: Effect): void;
    /**
     * Gets the number of parts in the compound.
     */
    get partCount(): number;
    /**
     * Gets the part visibility array.
     */
    get partVisibility(): number[];
    /**
     * Sets the world matrix for a specific part of the compound.
     * This will trigger a re-sort of the mesh.
     * The `_partMatrices` array is automatically extended when `partIndex >= partCount`.
     * @param partIndex index of the part
     * @param worldMatrix the world matrix to set
     */
    setWorldMatrixForPart(partIndex: number, worldMatrix: Matrix): void;
    /**
     * Gets the world matrix for a specific part of the compound.
     * @param partIndex index of the part, that must be between 0 and partCount - 1
     * @returns the world matrix for the part, or the current world matrix of the mesh if the part is not found
     */
    getWorldMatrixForPart(partIndex: number): Matrix;
    /**
     * Gets the visibility for a specific part of the compound.
     * @param partIndex index of the part, that must be between 0 and partCount - 1
     * @returns the visibility value (0.0 to 1.0) for the part
     */
    getPartVisibility(partIndex: number): number;
    /**
     * Sets the visibility for a specific part of the compound.
     * @param partIndex index of the part, that must be between 0 and partCount - 1
     * @param value the visibility value (0.0 to 1.0) to set
     */
    setPartVisibility(partIndex: number, value: number): void;
    protected _copyTextures(source: GaussianSplattingMeshBase): void;
    protected _onUpdateTextures(textureSize: Vector2): void;
    protected _updateSubTextures(splatPositions: Float32Array, covA: Uint16Array, covB: Uint16Array, colorArray: Uint8Array, lineStart: number, lineCount: number, sh?: Uint8Array[], partIndices?: Uint8Array): void;
    /**
     * Creates the part indices GPU texture the first time an incremental addPart introduces
     * compound data. Has no effect if the texture already exists or no partIndices are provided.
     * @param textureSize - Current texture dimensions
     * @param partIndices - Part index data; if undefined the method is a no-op
     */
    protected _ensurePartIndicesTexture(textureSize: Vector2, partIndices: Uint8Array | undefined): void;
    /**
     * Core implementation for adding one or more external GaussianSplattingMesh objects as new
     * parts. Writes directly into texture-sized CPU arrays and uploads in one pass — no merged
     * CPU splat buffer is ever constructed.
     *
     * @param others - Source meshes to append (must each be non-compound and fully loaded)
     * @param disposeOthers - Dispose source meshes after appending
     * @returns Proxy meshes and their assigned part indices
     */
    protected _addPartsInternal(others: GaussianSplattingMesh[], disposeOthers: boolean): {
        proxyMeshes: GaussianSplattingPartProxyMesh[];
        assignedPartIndices: number[];
    };
    /**
     * Add another mesh to this mesh, as a new part. This makes the current mesh a compound, if not already.
     * The source mesh's splat data is read directly — no merged CPU buffer is constructed.
     * @param other - The other mesh to add. Must be fully loaded before calling this method.
     * @param disposeOther - Whether to dispose the other mesh after adding it to the current mesh.
     * @returns a placeholder mesh that can be used to manipulate the part transform
     * @deprecated Use {@link GaussianSplattingCompoundMesh.addPart} instead.
     */
    addPart(other: GaussianSplattingMesh, disposeOther?: boolean): GaussianSplattingPartProxyMesh;
    /**
     * Remove a part from this compound mesh.
     * The remaining parts are rebuilt directly from their stored source mesh references —
     * no merged CPU splat buffer is read back. The current mesh is reset to a plain (single-part)
     * state and then each remaining source is re-added via addParts.
     * @param index - The index of the part to remove
     * @deprecated Use {@link GaussianSplattingCompoundMesh.removePart} instead.
     */
    removePart(index: number): void;
}
