/**
 * Owns the gsplat "world": the work buffer, versioned world states, allocation, octree/LOD
 * evaluation, streaming, budget enforcement, and the work-buffer bake. A single primary camera
 * (passed in to {@link GSplatWorld#update} / {@link GSplatWorld#bake}) drives LOD and color.
 *
 * The dependency is one-way: {@link GSplatManager} reads world data through getters and drives
 * mutation through explicit methods. The world never calls into the renderer, sorters, interval
 * compaction, or projector — instead it writes results into caller-owned result objects, and the
 * manager reacts (e.g. rebinding the renderer's data source on a work-buffer recreation).
 *
 * @ignore
 */
export class GSplatWorld {
    /**
     * @param {GraphicsDevice} device - The graphics device.
     * @param {Scene} scene - The scene.
     */
    constructor(device: GraphicsDevice, scene: Scene);
    /** @type {GraphicsDevice} */
    _device: GraphicsDevice;
    /** @type {Scene} */
    _scene: Scene;
    /** @type {GSplatWorkBuffer} */
    _workBuffer: GSplatWorkBuffer;
    /** @type {Map<number, GSplatWorldState>} */
    _worldStates: Map<number, GSplatWorldState>;
    /** @type {number} */
    _lastWorldStateVersion: number;
    /**
     * The render-ready version: the version the work buffer is baked to and rendered from. Advanced
     * exclusively via {@link GSplatWorld#markSorted}. (Formerly `GSplatManager.sortedVersion`.)
     *
     * @type {number}
     */
    _currentVersion: number;
    /** @type {boolean} */
    _worldStateDirty: boolean;
    /** @type {number} */
    _workBufferFormatVersion: number;
    /** @type {boolean} */
    _workBufferRebuildRequired: boolean;
    /** @type {number} */
    _bufferCopyUploaded: number;
    /** @type {number} */
    _bufferCopyTotal: number;
    /** @type {GSplatPlacementStateTracker} */
    _stateTracker: GSplatPlacementStateTracker;
    /** @type {number} */
    _framesTillFullUpdate: number;
    /**
     * Latched request for a full LOD update, raised by the 10-frame cadence metronome and cleared
     * when fulfilled (when the back-pressure gate allows). Decouples "a full update is due" from
     * "we may run it this frame", so a tick deferred by back-pressure fires on the next available
     * frame rather than being lost until the next 10-frame mark.
     *
     * @type {boolean}
     */
    _lodUpdateRequested: boolean;
    /** @type {Vec3} */
    _lastLodCameraPos: Vec3;
    /** @type {Vec3} */
    _lastLodCameraFwd: Vec3;
    /** @type {number} */
    _lastLodCameraFov: number;
    /** @type {GSplatBudgetBalancer} */
    _budgetBalancer: GSplatBudgetBalancer;
    /** @type {number} */
    _budgetScale: number;
    /** @type {BlockAllocator} */
    _allocator: BlockAllocator;
    /** @type {Map<number, MemBlock>} */
    _allocationMap: Map<number, MemBlock>;
    /** @type {Vec3} */
    _lastColorUpdateCameraPos: Vec3;
    /** @type {GSplatPlacement[]} */
    _layerPlacements: GSplatPlacement[];
    /** @type {boolean} */
    _layerPlacementsDirty: boolean;
    /** @type {boolean} */
    _placementSetChanged: boolean;
    /** @type {Map<GSplatPlacement, GSplatOctreeInstance>} */
    _octreeInstances: Map<GSplatPlacement, GSplatOctreeInstance>;
    /** @type {GSplatOctreeInstance[]} */
    _octreeInstancesToDestroy: GSplatOctreeInstance[];
    /** @type {boolean} */
    _hasNewOctreeInstances: boolean;
    /**
     * Suppresses ready=true in frame:ready until a fullUpdate cycle runs. Only set when octree
     * instances exist and params change (dirty).
     *
     * @type {boolean}
     */
    _awaitingLodUpdate: boolean;
    destroy(): void;
    /** @type {GSplatWorkBuffer} */
    get workBuffer(): GSplatWorkBuffer;
    /** @type {number} */
    get currentVersion(): number;
    /** @type {number} */
    get lastWorldStateVersion(): number;
    /** @type {number} */
    get bufferCopyUploaded(): number;
    /** @type {number} */
    get bufferCopyTotal(): number;
    /** @type {boolean} */
    get awaitingLodUpdate(): boolean;
    /** @type {boolean} */
    get hasOctreeInstances(): boolean;
    /**
     * Total pending loads across all octree instances (including environment).
     *
     * @type {number}
     */
    get pendingLoadCount(): number;
    /**
     * The render-ready world state, or undefined if not yet created.
     *
     * @type {GSplatWorldState|undefined}
     */
    get currentState(): GSplatWorldState | undefined;
    /**
     * Looks up a world state by version.
     *
     * @param {number} version - The world state version.
     * @returns {GSplatWorldState|undefined} The world state, or undefined.
     */
    getState(version: number): GSplatWorldState | undefined;
    /**
     * True when frustum culling can run for the given renderer (bounds data available). The renderer
     * type gate stays on the manager; this only reports bounds availability.
     *
     * @type {boolean}
     */
    get hasBounds(): boolean;
    /**
     * Resets per-frame buffer-copy stats. Must run before any bake/rebuild of the frame (including
     * the CPU sorter's async onSorted path, which the manager applies before {@link GSplatWorld#update}).
     */
    resetFrameStats(): void;
    /**
     * Marks the world state and/or work buffer as needing a rebuild. Called by the manager on
     * renderer-mode transitions (the manager must not poke the private flags directly).
     *
     * @param {object} [opts] - Options.
     * @param {boolean} [opts.worldState] - Force a world-state rebuild.
     * @param {boolean} [opts.workBuffer] - Force a full work-buffer rebuild.
     */
    invalidate({ worldState, workBuffer }?: {
        worldState?: boolean;
        workBuffer?: boolean;
    }): void;
    /**
     * Resets the render-ready state's sort bookkeeping so the next sort triggers a full rebuild
     * (used when switching to the CPU-sort renderer). Returns the state's splats for the manager to
     * feed its CPU sorter, or null if no state exists.
     *
     * @returns {GSplatInfo[]|null} The current state's splats, or null.
     */
    invalidateSortState(): GSplatInfo[] | null;
    /**
     * Detects work-buffer format changes and recreates / syncs the work buffer. Must run before the
     * CPU sorter's pending results are applied (so onSorted rebuilds into the current buffer).
     *
     * @param {{ bufferRecreated: boolean, sortNeeded: boolean }} result - Caller-owned result object.
     * @returns {{ bufferRecreated: boolean, sortNeeded: boolean }} The populated result.
     */
    syncFormat(result: {
        bufferRecreated: boolean;
        sortNeeded: boolean;
    }): {
        bufferRecreated: boolean;
        sortNeeded: boolean;
    };
    /**
     * Supply the placements to use. Updates octree instances and the non-octree placement list,
     * flagging dirtiness. Called infrequently (when the layer's placements change).
     *
     * @param {GSplatPlacement[]} placements - The placements to reconcile with.
     */
    reconcile(placements: GSplatPlacement[]): void;
    /**
     * Per-frame LOD/streaming pass: evaluates LOD against the primary camera (subject to the
     * back-pressure gate), enforces budget, and creates a new world-state version when needed.
     *
     * @param {GraphNode} camera - The primary camera driving LOD/streaming.
     * @param {boolean} allowLodUpdate - Back-pressure gate (false when the CPU sorter is busy).
     * @param {boolean} requireCenters - Whether resources without a centers buffer must be skipped
     * (CPU sort path).
     * @param {{ newVersion: boolean, overdrawDirty: boolean, sortNeeded: boolean }} result -
     * Caller-owned result object the manager reacts to.
     * @returns {{ newVersion: boolean, overdrawDirty: boolean, sortNeeded: boolean }} The populated result.
     */
    update(camera: GraphNode, allowLodUpdate: boolean, requireCenters: boolean, result: {
        newVersion: boolean;
        overdrawDirty: boolean;
        sortNeeded: boolean;
    }): {
        newVersion: boolean;
        overdrawDirty: boolean;
        sortNeeded: boolean;
    };
    /**
     * Creates a new world state version when placements/resources changed. Returns whether a new
     * version was created. Does NOT feed the CPU sorter (the manager does that on a new version).
     *
     * @param {boolean} requireCenters - Whether resources without centers must be skipped.
     * @returns {boolean} True if a new world-state version was created.
     * @private
     */
    private _updateWorldState;
    /**
     * Advances the render-ready version to `version` (cleaning up older states) and, on the first
     * sort of that version, rebuilds the work buffer. The manager calls this from the GPU sort
     * paths and the CPU onSorted callback. Atomic: cleanup + version-advance happen together.
     *
     * @param {number} version - The version that has been sorted.
     * @param {number} count - The splat count for the work-buffer rebuild / renderer update.
     * @param {GraphNode} camera - The primary camera (for color bake).
     * @param {boolean} updateBounds - Whether to upload frustum-culling bounds (false for CPU sort).
     * @param {{ rebuilt: boolean, count: number, textureSize: number }} result - Caller-owned result.
     * @returns {{ rebuilt: boolean, count: number, textureSize: number }} The populated result. When
     * `rebuilt` is true the manager must call `renderer.update(count, textureSize)`.
     */
    markSorted(version: number, count: number, camera: GraphNode, updateBounds: boolean, result: {
        rebuilt: boolean;
        count: number;
        textureSize: number;
    }): {
        rebuilt: boolean;
        count: number;
        textureSize: number;
    };
    /**
     * Applies a completed CPU sort: advances the render-ready version (via markSorted) and uploads
     * the sorted order texture. The manager rebinds the renderer afterwards.
     *
     * @param {number} version - The sorted version.
     * @param {number} count - The sorted splat count.
     * @param {Uint32Array} orderData - The sorted order data.
     * @param {GraphNode} camera - The primary camera (for color bake on first sort).
     * @param {boolean} updateBounds - Whether to upload frustum-culling bounds (false for CPU sort).
     * @param {{ rebuilt: boolean, count: number, textureSize: number }} result - Caller-owned result.
     * @returns {{ rebuilt: boolean, count: number, textureSize: number }} The populated result.
     */
    onSorted(version: number, count: number, orderData: Uint32Array, camera: GraphNode, updateBounds: boolean, result: {
        rebuilt: boolean;
        count: number;
        textureSize: number;
    }): {
        rebuilt: boolean;
        count: number;
        textureSize: number;
    };
    /**
     * Materializes the work buffer for the given (render-ready) version: a full rebuild when one is
     * pending, otherwise an incremental update. Refreshes color tracking. Camera drives the SH color
     * bake.
     *
     * @param {number} version - The render-ready version to bake.
     * @param {GraphNode} camera - The primary camera (for color bake).
     * @param {boolean} updateBounds - Whether to upload frustum-culling bounds (false for CPU sort).
     * @param {{ rebuilt: boolean, count: number, textureSize: number, sortNeeded: boolean }} result -
     * Caller-owned result. When `rebuilt` is true the manager must call `renderer.update(count,
     * textureSize)`, `renderer.setOrderData()` and `intervalCompaction.invalidateUpload()`. When
     * `sortNeeded` is true (a splat moved during the incremental update) the manager must re-sort.
     * @returns {{ rebuilt: boolean, count: number, textureSize: number, sortNeeded: boolean }} The populated result.
     */
    bake(version: number, camera: GraphNode, updateBounds: boolean, result: {
        rebuilt: boolean;
        count: number;
        textureSize: number;
        sortNeeded: boolean;
    }): {
        rebuilt: boolean;
        count: number;
        textureSize: number;
        sortNeeded: boolean;
    };
    /**
     * Rebuilds the work buffer for a world state: resizes if needed, renders changed (or all) splats,
     * syncs transforms, and applies pending file-release requests. Does NOT touch the renderer — the
     * caller updates the renderer's count/textureSize from {@link GSplatWorld#bake} /
     * {@link GSplatWorld#markSorted} results.
     *
     * @param {GSplatWorldState} worldState - The world state to rebuild for.
     * @param {number} count - The number of splats (unused here; surfaced via the result for the renderer).
     * @param {boolean} forceFullRebuild - Force rendering all splats (e.g. format change).
     * @param {GraphNode} camera - The primary camera (for color bake).
     * @param {boolean} updateBounds - Whether to upload bounds/transforms for frustum culling. False
     * for the CPU-sort renderer, whose frustum-culler storage buffers are not allocated.
     * @private
     */
    private rebuildWorkBuffer;
    /**
     * Cleans up old world states between the last render-ready version and the new version. Merges
     * upload requirements from skipped states into the active state, then decrements ref counts and
     * destroys old states. Note: reads the current `_currentVersion` (not yet advanced to newVersion).
     *
     * @param {number} newVersion - The new version to clean up to.
     */
    cleanupOldWorldStates(newVersion: number): void;
    /**
     * Applies incremental work buffer updates for splats that have changed. Detects transform changes
     * and color update thresholds, then batch renders updates. Reports whether any splat moved (the
     * manager uses this to set sortNeeded).
     *
     * @param {GSplatWorldState} state - The world state to update.
     * @param {GraphNode} camera - The primary camera (for color delta + bake).
     * @returns {boolean} True if any splat moved (requires re-sort).
     */
    applyWorkBufferUpdates(state: GSplatWorldState, camera: GraphNode): boolean;
    /**
     * Tests if the camera has moved or rotated enough to require LOD update.
     *
     * @param {GraphNode} camera - The primary camera.
     * @returns {boolean} True if camera moved/rotated over thresholds, otherwise false.
     */
    testCameraMovedForLod(camera: GraphNode): boolean;
    /**
     * Updates the camera tracking state for color accumulation calculations.
     *
     * @param {GraphNode} camera - The primary camera.
     */
    updateColorCameraTracking(camera: GraphNode): void;
    /**
     * Determines the colorization mode for rendering based on debug flags.
     *
     * @returns {Array<number[]>|undefined} Color array for debug visualization, or undefined for normal rendering.
     */
    getDebugColors(): Array<number[]> | undefined;
    /**
     * Calculates camera translation delta since last color update. Updates and returns the shared
     * _cameraDeltas object.
     *
     * @param {GraphNode} camera - The primary camera.
     * @returns {{ translationDelta: number }} Shared camera movement deltas object.
     */
    calculateColorCameraDeltas(camera: GraphNode): {
        translationDelta: number;
    };
    /**
     * Computes max world-space distance across all octree instances. Used for sqrt-based bucket
     * distribution in budget balancing.
     *
     * @param {GraphNode} camera - The primary camera.
     * @returns {number} Maximum world-space distance, minimum 1 to avoid division by zero.
     * @private
     */
    private computeGlobalMaxDistance;
    /**
     * Enforces global splat budget across all octree instances using a phased approach.
     *
     * @param {number} budget - Target splat budget from GSplatParams.splatBudget.
     * @param {GraphNode} camera - The primary camera.
     * @private
     */
    private _enforceBudget;
    /**
     * Computes the world-space union of all placement AABBs. Returns the shared bounding box, or
     * null if there are no placements. The manager applies it to the renderer's mesh instance.
     *
     * @returns {BoundingBox|null} The aggregate AABB, or null.
     */
    computeAggregateAabb(): BoundingBox | null;
    /**
     * Accumulates a placement's transformed AABB into the running mesh-instance AABB.
     *
     * @param {GSplatPlacement} placement - The placement.
     * @param {boolean} initialized - Whether the running AABB has been initialized.
     * @returns {boolean} The updated initialized flag.
     * @private
     */
    private _accumulatePlacementAabb;
    /**
     * Ticks octree cooldown timers once per frame per unique octree.
     */
    tickCooldowns(): void;
    /**
     * Forces LOD re-evaluation on all octree instances (e.g. after frame:ready listeners changed
     * params).
     */
    markInstancesNeedLodUpdate(): void;
    /**
     * Prepares sort parameters data for the sorter worker. Reads world-state data; the manager owns
     * the sorter and posts the result.
     *
     * @param {GSplatWorldState} worldState - The world state containing all needed data.
     * @returns {object} Data for the sorter worker.
     */
    prepareSortParameters(worldState: GSplatWorldState): object;
}
import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js';
import type { Scene } from '../scene.js';
import { GSplatWorkBuffer } from './gsplat-work-buffer.js';
import { GSplatWorldState } from './gsplat-world-state.js';
import { GSplatPlacementStateTracker } from './gsplat-placement-state-tracker.js';
import { Vec3 } from '../../core/math/vec3.js';
import { GSplatBudgetBalancer } from './gsplat-budget-balancer.js';
import { BlockAllocator } from '../../core/block-allocator.js';
import type { MemBlock } from '../../core/block-allocator.js';
import type { GSplatPlacement } from './gsplat-placement.js';
import { GSplatOctreeInstance } from './gsplat-octree-instance.js';
import { GSplatInfo } from './gsplat-info.js';
import type { GraphNode } from '../graph-node.js';
import { BoundingBox } from '../../core/shape/bounding-box.js';
