/**
 * @import { BoundingBox } from '../../../core/shape/bounding-box.js'
 * @import { Entity } from '../../entity.js'
 * @import { EventHandle } from '../../../core/event-handle.js'
 * @import { GSplatComponentSystem } from './system.js'
 * @import { ShaderMaterial } from '../../../scene/materials/shader-material.js'
 */
/**
 * The GSplatComponent enables an {@link Entity} to render 3D Gaussian Splats. Splats are always
 * loaded from {@link Asset}s rather than being created programmatically. The asset type is
 * `gsplat` which supports multiple file formats including `.ply`, `.sog`, `.meta.json` (SOGS
 * format), and `.lod-meta.json` (streaming LOD format).
 *
 * You should never need to use the GSplatComponent constructor directly. To add an
 * GSplatComponent to an {@link Entity}, use {@link Entity#addComponent}:
 *
 * ```javascript
 * const entity = pc.Entity();
 * entity.addComponent('gsplat', {
 *     asset: asset
 * });
 * ```
 *
 * Once the GSplatComponent is added to the entity, you can access it via the {@link Entity#gsplat}
 * property:
 *
 * ```javascript
 * entity.gsplat.customAabb = new pc.BoundingBox(new pc.Vec3(), new pc.Vec3(10, 10, 10));
 *
 * console.log(entity.gsplat.customAabb);
 * ```
 *
 * ## Unified Rendering
 *
 * The {@link GSplatComponent#unified} property enables unified rendering mode, which provides
 * advanced features for Gaussian Splats:
 *
 * - **Global Sorting**: Multiple splat components are sorted together in a single unified sort,
 *   eliminating visibility artifacts and popping effects when splat components overlap.
 * - **LOD Streaming**: Dynamically loads and renders appropriate levels of detail based on camera
 *   distance, enabling efficient rendering of massive splat scenes.
 *
 * ```javascript
 * // Enable unified rendering for advanced features
 * entity.gsplat.unified = true;
 * ```
 *
 * Note: The `unified` property can only be changed when the component is disabled.
 *
 * Relevant Engine API examples:
 *
 * - [Simple Splat Loading](https://playcanvas.github.io/#/gaussian-splatting/simple)
 * - [Global Sorting](https://playcanvas.github.io/#/gaussian-splatting/global-sorting)
 * - [LOD](https://playcanvas.github.io/#/gaussian-splatting/lod)
 * - [LOD Instances](https://playcanvas.github.io/#/gaussian-splatting/lod-instances)
 * - [LOD Streaming](https://playcanvas.github.io/#/gaussian-splatting/lod-streaming)
 * - [LOD Streaming with Spherical Harmonics](https://playcanvas.github.io/#/gaussian-splatting/lod-streaming-sh)
 * - [Multi-Splat](https://playcanvas.github.io/#/gaussian-splatting/multi-splat)
 * - [Multi-View](https://playcanvas.github.io/#/gaussian-splatting/multi-view)
 * - [Picking](https://playcanvas.github.io/#/gaussian-splatting/picking)
 * - [Reveal Effect](https://playcanvas.github.io/#/gaussian-splatting/reveal)
 * - [Shader Effects](https://playcanvas.github.io/#/gaussian-splatting/shader-effects)
 * - [Spherical Harmonics](https://playcanvas.github.io/#/gaussian-splatting/spherical-harmonics)
 *
 * @hideconstructor
 * @category Graphics
 */
export class GSplatComponent extends Component {
    /**
     * Create a new GSplatComponent.
     *
     * @param {GSplatComponentSystem} system - The ComponentSystem that created this Component.
     * @param {Entity} entity - The Entity that this Component is attached to.
     */
    constructor(system: GSplatComponentSystem, entity: Entity);
    /** @private */
    private _layers;
    /**
     * @type {GSplatInstance|null}
     * @private
     */
    private _instance;
    /**
     * @type {GSplatPlacement|null}
     * @private
     */
    private _placement;
    /**
     * @type {ShaderMaterial|null}
     * @private
     */
    private _materialTmp;
    /** @private */
    private _highQualitySH;
    /**
     * LOD distance thresholds, stored as a copy.
     *
     * @type {number[]|null}
     * @private
     */
    private _lodDistances;
    /**
     * Target number of splats to render for this component. The system will adjust LOD levels
     * bidirectionally to reach this budget. Set to 0 to disable (default).
     *
     * @type {number}
     * @private
     */
    private _splatBudget;
    /**
     * @type {BoundingBox|null}
     * @private
     */
    private _customAabb;
    /**
     * @type {AssetReference}
     * @private
     */
    private _assetReference;
    /**
     * @type {EventHandle|null}
     * @private
     */
    private _evtLayersChanged;
    /**
     * @type {EventHandle|null}
     * @private
     */
    private _evtLayerAdded;
    /**
     * @type {EventHandle|null}
     * @private
     */
    private _evtLayerRemoved;
    /** @private */
    private _castShadows;
    /**
     * Whether to use the unified gsplat rendering.
     *
     * @type {boolean}
     * @private
     */
    private _unified;
    /**
     * Sets a custom object space bounding box for visibility culling of the attached gsplat.
     *
     * @type {BoundingBox|null}
     */
    set customAabb(value: BoundingBox | null);
    /**
     * Gets the custom object space bounding box for visibility culling of the attached gsplat.
     *
     * @type {BoundingBox|null}
     */
    get customAabb(): BoundingBox | null;
    /**
     * Sets a {@link GSplatInstance} on the component. If not set or loaded, it returns null.
     *
     * @type {GSplatInstance|null}
     * @ignore
     */
    set instance(value: GSplatInstance | null);
    /**
     * Gets the {@link GSplatInstance} on the component.
     *
     * @type {GSplatInstance|null}
     * @ignore
     */
    get instance(): GSplatInstance | null;
    /**
     * Sets the material used to render the gsplat.
     *
     * **Note:** This setter is only supported when {@link unified} is `false`. When it's true, multiple
     * gsplat components share a single material per camera/layer combination. To access materials in
     * unified mode, use {@link GsplatComponentSystem#getGSplatMaterial}.
     *
     * @param {ShaderMaterial} value - The material instance.
     */
    set material(value: ShaderMaterial);
    /**
     * Gets the material used to render the gsplat.
     *
     * **Note:** This getter returns `null` when {@link unified} is `true`. In unified mode, materials are
     * organized per camera/layer combination rather than per component. To access materials in
     * unified mode, use {@link GsplatComponentSystem#getGSplatMaterial}.
     *
     * @type {ShaderMaterial|null}
     */
    get material(): ShaderMaterial | null;
    /**
     * Sets whether to use the high quality or the approximate (but fast) spherical-harmonic calculation when rendering SOGS data.
     *
     * The low quality approximation evaluates the scene's spherical harmonic contributions
     * along the camera's Z-axis instead of using each gaussian's view vector. This results
     * in gaussians being accurate at the center of the screen and becoming less accurate
     * as they appear further from the center. This is a good trade-off for performance
     * when rendering large SOGS datasets, especially on mobile devices.
     *
     * Defaults to false.
     *
     * @type {boolean}
     */
    set highQualitySH(value: boolean);
    /**
     * Gets whether the high quality (true) or the fast approximate (false) spherical-harmonic calculation is used when rendering SOGS data.
     *
     * @type {boolean}
     */
    get highQualitySH(): boolean;
    /**
     * Sets whether gsplat will cast shadows for lights that have shadow casting enabled. Defaults
     * to false.
     *
     * @type {boolean}
     */
    set castShadows(value: boolean);
    /**
     * Gets whether gsplat will cast shadows for lights that have shadow casting enabled.
     *
     * @type {boolean}
     */
    get castShadows(): boolean;
    /**
     * Sets LOD distance thresholds used by octree-based gsplat rendering. The provided array
     * is copied.
     *
     * @type {number[]|null}
     */
    set lodDistances(value: number[] | null);
    /**
     * Gets a copy of LOD distance thresholds previously set, or null when not set.
     *
     * @type {number[]|null}
     */
    get lodDistances(): number[] | null;
    /**
     * Sets the target number of splats to render for this component. The system will adjust LOD
     * levels bidirectionally to reach this budget:
     * - When over budget: degrades quality for less important geometry
     * - When under budget: upgrades quality for more important geometry
     *
     * This ensures optimal use of available rendering budget while prioritizing quality for
     * closer/more important geometry.
     *
     * Set to 0 to disable the budget (default). When disabled, optimal LOD is determined purely
     * by distance and configured LOD parameters.
     *
     * Only applies to octree-based gsplat rendering in unified mode.
     *
     * @type {number}
     */
    set splatBudget(value: number);
    /**
     * Gets the splat budget limit for this component.
     *
     * @type {number}
     */
    get splatBudget(): number;
    /**
     * Sets whether to use the unified gsplat rendering. Can be changed only when the component is
     * not enabled. Default is false.
     *
     * @type {boolean}
     * @alpha
     */
    set unified(value: boolean);
    /**
     * Gets whether to use the unified gsplat rendering.
     *
     * @type {boolean}
     * @alpha
     */
    get unified(): boolean;
    /**
     * Sets an array of layer IDs ({@link Layer#id}) to which this gsplat should belong. Don't
     * push, pop, splice or modify this array. If you want to change it, set a new one instead.
     *
     * @type {number[]}
     */
    set layers(value: number[]);
    /**
     * Gets the array of layer IDs ({@link Layer#id}) to which this gsplat belongs.
     *
     * @type {number[]}
     */
    get layers(): number[];
    /**
     * Sets the gsplat asset for this gsplat component. Can also be an asset id.
     *
     * @type {Asset|number}
     */
    set asset(value: Asset | number);
    /**
     * Gets the gsplat asset id for this gsplat component.
     *
     * @type {Asset|number}
     */
    get asset(): Asset | number;
    /** @private */
    private destroyInstance;
    /** @private */
    private addToLayers;
    removeFromLayers(): void;
    /** @private */
    private onRemoveChild;
    /** @private */
    private onInsertChild;
    onRemove(): void;
    onLayersChanged(oldComp: any, newComp: any): void;
    onLayerAdded(layer: any): void;
    onLayerRemoved(layer: any): void;
    /**
     * Stop rendering this component without removing its mesh instance from the scene hierarchy.
     */
    hide(): void;
    /**
     * Enable rendering of the component if hidden using {@link GSplatComponent#hide}.
     */
    show(): void;
    _onGSplatAssetAdded(): void;
    _onGSplatAssetLoad(): void;
    _onGSplatAssetUnload(): void;
    _onGSplatAssetRemove(): void;
}
import { Component } from '../component.js';
import type { BoundingBox } from '../../../core/shape/bounding-box.js';
import { GSplatInstance } from '../../../scene/gsplat/gsplat-instance.js';
import type { ShaderMaterial } from '../../../scene/materials/shader-material.js';
import { Asset } from '../../asset/asset.js';
import type { GSplatComponentSystem } from './system.js';
import type { Entity } from '../../entity.js';
