/**
 * GSplatManager manages the rendering of splats using a work buffer, where all active splats are
 * stored and rendered from. It owns the {@link GSplatWorld} (work buffer, world-state versions,
 * streaming, bake), the world version lifecycle ({@link GSplatWorld#markSorted}/`onSorted`), and —
 * for the CPU-sort path ({@link GSplatQuadRenderer}) — a web-worker sorter. Each frame it bakes the
 * render-ready world state and then delegates per-view work to the active renderer:
 *
 * - CPU sort (WebGPU + WebGL): the manager sends camera + centers to the worker, which returns a
 *   sorted order; the quad renderer's vertex shader reads `orderBuffer[vertexId] → splatId`. No
 *   GPU culling.
 * - GPU sort ({@link GSplatHybridRenderer}, WebGPU only): the renderer owns the interval cull +
 *   compaction, projector, and radix sort; the manager just marks the version sorted and calls
 *   {@link GSplatRenderer#prepareRenderView}.
 *
 * @ignore
 */
export class GSplatManager {
    /**
     * @param {GraphicsDevice} device - The graphics device.
     * @param {GSplatDirector} director - The director.
     * @param {Layer} layer - The layer.
     * @param {GraphNode} cameraNode - The camera node.
     */
    constructor(device: GraphicsDevice, director: GSplatDirector, layer: Layer, cameraNode: GraphNode);
    /** @type {GraphicsDevice} */
    device: GraphicsDevice;
    /** @type {GraphNode} */
    node: GraphNode;
    /**
     * Owns the work buffer, versioned world states, allocation, octree/LOD evaluation, streaming,
     * budget, and the work-buffer bake. Created 1:1 per manager (no sharing yet).
     *
     * @type {GSplatWorld}
     */
    world: GSplatWorld;
    /** @type {GSplatRenderer} */
    renderer: GSplatRenderer;
    /**
     * Casts directional shadows for the GPU-sort (hybrid) forward renderer, which cannot self-cast.
     * Null when the forward renderer is CPU-sort (the quad renderer self-casts) or when this
     * manager has no shadow render mode. Shares this manager's {@link GSplatWorld}.
     *
     * @type {GSplatShadowRenderer|null}
     */
    shadowRenderer: GSplatShadowRenderer | null;
    /**
     * Shared GPU scratch for the GPU-sort (hybrid) path, created while a GPU-sort renderer is in use
     * and injected into both the forward {@link GSplatHybridRenderer} and the
     * {@link GSplatShadowRenderer} so they share the compaction candidate buffer. Null for the
     * CPU-sort (quad) renderer.
     *
     * @type {GSplatHybridRendererScratch|null}
     * @private
     */
    private _hybridScratch;
    /**
     * The currently active renderer mode. Starts as undefined so the first
     * prepareRendererMode() call always creates the appropriate resources.
     *
     * @type {number|undefined}
     */
    activeRenderer: number | undefined;
    /**
     * CPU-based sorter (used by the quad renderer; the hybrid renderer owns its own GPU sort).
     *
     * @type {GSplatUnifiedSorter|null}
     */
    cpuSorter: GSplatUnifiedSorter | null;
    /**
     * Tracks last seen centersVersion per resource ID for detecting centers updates. Used to feed
     * the CPU sorter when the world creates a new world-state version.
     *
     * @type {Map<number, number>}
     * @private
     */
    private _centersVersions;
    /** @type {Vec3} */
    lastSortCameraPos: Vec3;
    /** @type {Vec3} */
    lastSortCameraFwd: Vec3;
    /** @type {boolean} */
    sortNeeded: boolean;
    /**
     * Event handle for the graphics device restored event.
     *
     * @type {EventHandle|null}
     * @private
     */
    private _deviceRestoredEvent;
    /** @type {GraphNode} */
    cameraNode: GraphNode;
    /** @type {Scene} */
    scene: Scene;
    /**
     * Bitmask flags controlling which render passes this manager participates in.
     *
     * @type {number|undefined}
     */
    renderMode: number | undefined;
    /**
     * Persistent result objects written (out-param) by the {@link GSplatWorld} APIs to avoid
     * per-frame allocation. Consumed synchronously by the manager after each call.
     *
     * @private
     */
    private _updateResult;
    /** @private */
    private _bakeResult;
    /** @private */
    private _markResult;
    /** @private */
    private _formatResult;
    /**
     * Frame token of the last {@link updateStreaming} run, for once-per-frame dedup between the
     * component-system streaming tick and the render path.
     *
     * @type {number}
     * @private
     */
    private _lastStreamToken;
    /**
     * Whether the most recent streaming pass produced new data a render would show (new world-state
     * version or work-buffer recreation). Used by the director to decide whether to fire frame:request.
     *
     * @type {boolean}
     * @private
     */
    private _streamAdvanced;
    /**
     * Reused per-call parameter bag passed to the renderer's forward {@link GSplatRenderer#prepareRenderView}.
     * Avoids per-frame allocation and keeps the renderer free of a back-reference to the manager/scene.
     *
     * @type {GSplatRenderViewParams}
     * @private
     */
    private _renderViewParams;
    /**
     * Reused per-call parameter bag passed to the renderer's {@link GSplatRenderer#preparePickingView}.
     * Separate from {@link _renderViewParams} so mid-frame picking can't corrupt the forward params.
     *
     * @type {GSplatRenderViewParams}
     * @private
     */
    private _pickParams;
    director: GSplatDirector;
    layer: Layer;
    destroy(): void;
    _destroyed: boolean;
    /**
     * Handles a graphics context restore: the work buffer render target is recreated empty, so
     * force a full rebuild and re-sort to re-materialize the splats from the (auto-restored) source
     * textures.
     *
     * Skipped when the world has streaming octree instances: those destroy and asynchronously
     * reload their source resources from URL via their own device-lost handling, and rebuilding the
     * work buffer here would render from textures that have been destroyed (and not yet reloaded).
     *
     * @private
     */
    private _onDeviceRestored;
    /**
     * Destroys CPU sorting resources (worker-based sorter).
     *
     * @private
     */
    private destroyCpuSorting;
    /**
     * Creates the CPU sorter and prepares it for the current world state. Disables any
     * GPU-side indirect draw and hides the mesh until the first sort result arrives.
     *
     * @private
     */
    private initCpuSorting;
    get material(): import("../materials/shader-material.js").ShaderMaterial;
    /**
     * Number of work-buffer blocks uploaded this frame (forwarded from the world for stats).
     *
     * @type {number}
     */
    get bufferCopyUploaded(): number;
    /**
     * Total number of work-buffer blocks this frame (forwarded from the world for stats).
     *
     * @type {number}
     */
    get bufferCopyTotal(): number;
    /**
     * True when the CPU sorter has a completed sort result waiting to be applied by a render. Used
     * by the director to request a render so the pending result is applied.
     *
     * @type {boolean}
     */
    get hasPendingSort(): boolean;
    /**
     * Dispatches a renderer-specific pick pipeline and returns the configured pick mesh instance.
     * The hybrid renderer refreshes its shared projector/sort buffers for the picker camera and
     * returns a transient pick mesh.
     *
     * @param {object} camera - The camera.
     * @param {number} width - Pick target width.
     * @param {number} height - Pick target height.
     * @returns {import('../mesh-instance.js').MeshInstance|null} The pick mesh instance, or null.
     */
    prepareForPicking(camera: object, width: number, height: number): import("../mesh-instance.js").MeshInstance | null;
    /**
     * Writes the current scene gsplat params into a renderer per-view parameter bag. Lets the
     * renderer run its GPU pipeline without a back-reference to the manager or scene.
     *
     * @param {GSplatRenderViewParams} p - The parameter bag to populate.
     * @private
     */
    private _writeGsplatParams;
    /**
     * Fills and returns the reused forward-view parameter bag for the manager's camera.
     *
     * @returns {GSplatRenderViewParams} The populated {@link _renderViewParams}.
     * @private
     */
    private _fillRenderViewParams;
    /**
     * Fills and returns the reused picking parameter bag for the picker camera.
     *
     * @param {object} camera - The picker camera.
     * @param {number} width - Pick target width.
     * @param {number} height - Pick target height.
     * @returns {GSplatRenderViewParams} The populated {@link _pickParams}.
     * @private
     */
    private _fillPickParams;
    /**
     * Creates the CPU sorter (Web Worker based).
     *
     * @returns {GSplatUnifiedSorter} The created sorter.
     */
    createSorter(): GSplatUnifiedSorter;
    /**
     * Sets the render mode for this manager and its renderer.
     *
     * @param {number} renderMode - Bitmask flags controlling render passes (GSPLAT_FORWARD, GSPLAT_SHADOW, or both).
     * @ignore
     */
    setRenderMode(renderMode: number): void;
    /**
     * Creates or destroys {@link shadowRenderer} to match the current render mode and forward
     * renderer. The GPU-sort (hybrid) renderer cannot self-cast shadows, so when shadow rendering
     * is requested and the forward renderer uses GPU sort, a dedicated {@link GSplatShadowRenderer}
     * casts on its behalf (sharing this manager's world). The CPU-sort quad renderer self-casts, so
     * no shadow renderer is created for it.
     *
     * @private
     */
    private _syncShadowRenderer;
    /**
     * Creates the renderer and sort resources for the given mode. Used at init time.
     *
     * @param {number} mode - The GSPLAT_RENDERER_* constant.
     * @private
     */
    private _createRenderer;
    /**
     * Checks whether the resolved renderer mode has changed and transitions to the new mode
     * (CPU raster quad <-> hybrid GPU sort).
     *
     * @private
     */
    private prepareRendererMode;
    /**
     * Supply the manager with the placements to use. This is used to update the manager when the
     * layer's placements have changed, called infrequently.
     *
     * @param {GSplatPlacement[]} placements - The placements to reconcile with.
     */
    reconcile(placements: GSplatPlacement[]): void;
    onSorted(count: any, version: any, orderData: any): void;
    /**
     * On the first sort of a world-state version, advances the render-ready version (cleanup +
     * first-sort work-buffer rebuild) and applies the renderer rebuild reaction. The world version
     * lifecycle is owned by the manager; the GPU pipeline (in the renderer) assumes a baked,
     * render-ready work buffer. This is the synchronous GPU-sort counterpart of {@link onSorted}
     * (the async CPU path). No-op once the version has been sorted before.
     *
     * @param {GSplatWorldState} worldState - The world state about to be sorted.
     * @private
     */
    private _markSortedIfNeeded;
    /**
     * Tests if the camera has moved enough to require re-sorting.
     * - For radial sorting: only position matters (rotation doesn't affect sort order)
     * - For directional sorting: only forward direction matters (position doesn't affect sort order)
     *
     * @returns {boolean} True if camera moved enough to require re-sorting, otherwise false.
     */
    testCameraMovedForSort(): boolean;
    /**
     * Fires the frame:ready event with current sorting and loading state.
     */
    fireFrameReadyEvent(): void;
    /**
     * CPU streaming pass: work-buffer format sync, renderer-mode transition, and the world's LOD /
     * octree streaming / world-state creation. Runs every frame from the component system's
     * framerender tick (even when rendering is skipped), and once from {@link update} on the render
     * path. Deduped via `token` so it runs at most once per frame. Performs no render-pass / draw
     * work — only CPU/IO and GPU resource creation.
     *
     * @param {number} token - Per-frame token; a repeated token is a no-op (returns the cached result).
     * @returns {boolean} True if new data was produced that a render would show (new world-state
     * version or work-buffer recreation).
     */
    updateStreaming(token: number): boolean;
    update(): number;
    /**
     * Post-cull shadow pass. Called from the director after cullComposition has fitted each
     * directional light's shadow-camera frustum, and before the frame graph renders the shadow
     * maps. Dispatches the per-light gsplat shadow cull and binds the results. No-op unless this
     * manager has a {@link shadowRenderer} (GPU-sort forward path with a shadow render mode).
     */
    updateShadows(): void;
    /**
     * Feeds the CPU sorter the centers for the splats in the latest world-state version. Called
     * after the world creates a new version (the version-change detection lives here because the
     * CPU sorter is manager-owned).
     *
     * @private
     */
    private _feedCpuSorterCenters;
    /**
     * Sorts the splats using CPU worker (asynchronous).
     *
     * @param {GSplatWorldState} lastState - The last world state.
     */
    sortCpu(lastState: GSplatWorldState): void;
}
import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js';
import { GraphNode } from '../graph-node.js';
import { GSplatWorld } from './gsplat-world.js';
import type { GSplatRenderer } from './gsplat-renderer.js';
import { GSplatShadowRenderer } from './gsplat-shadow-renderer.js';
import { GSplatUnifiedSorter } from './gsplat-unified-sorter.js';
import { Vec3 } from '../../core/math/vec3.js';
import type { Scene } from '../scene.js';
import type { GSplatDirector } from './gsplat-director.js';
import type { Layer } from '../layer.js';
import type { GSplatPlacement } from './gsplat-placement.js';
import type { GSplatWorldState } from './gsplat-world-state.js';
