/**
 * @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 { GSplatResourceBase } from '../../../scene/gsplat/gsplat-resource-base.js'
 * @import { ScopeId } from '../../../platform/graphics/scope-id.js'
 * @import { ShaderMaterial } from '../../../scene/materials/shader-material.js'
 * @import { StorageBuffer } from '../../../platform/graphics/storage-buffer.js'
 * @import { Texture } from '../../../platform/graphics/texture.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` (SOG
 * 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;
 * ```
 *
 * 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;
    /**
     * Unique identifier for this component, used by the picking system.
     *
     * @type {number}
     * @private
     */
    private _id;
    /**
     * @type {ShaderMaterial|null}
     * @private
     */
    private _materialTmp;
    /** @private */
    private _highQualitySH;
    /**
     * Base distance for the first LOD transition (LOD 0 to LOD 1).
     *
     * @type {number}
     * @private
     */
    private _lodBaseDistance;
    /**
     * Geometric multiplier between successive LOD distance thresholds.
     *
     * @type {number}
     * @private
     */
    private _lodMultiplier;
    /**
     * @type {BoundingBox|null}
     * @private
     */
    private _customAabb;
    /**
     * @type {AssetReference}
     * @private
     */
    private _assetReference;
    /**
     * Direct resource reference (for container splats).
     *
     * @type {GSplatResourceBase|null}
     * @private
     */
    private _resource;
    /**
     * @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;
    /**
     * Per-instance shader parameters. Stores objects with scopeId and data.
     *
     * @type {Map<string, {scopeId: ScopeId, data: *}>}
     * @private
     */
    private _parameters;
    /**
     * Render mode for work buffer updates.
     *
     * @type {number}
     * @private
     */
    private _workBufferUpdate;
    /**
     * Custom shader modify code for this component (object with code and pre-computed hash).
     *
     * @type {{ code: string, hash: number }|null}
     * @private
     */
    private _workBufferModifier;
    /**
     * 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.
     * Returns the custom AABB if set, otherwise falls back to the resource's AABB.
     *
     * @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#getMaterial}.
     *
     * @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#getMaterial}.
     *
     * @type {ShaderMaterial|null}
     */
    get material(): ShaderMaterial | null;
    /**
     * Sets whether to use the high quality or the approximate (but fast) spherical-harmonic calculation when rendering SOG 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 SOG 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 SOG 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 the base distance for the first LOD transition (LOD 0 to LOD 1). Objects closer
     * than this distance use the highest quality LOD. Each subsequent LOD level transitions
     * at a progressively larger distance, controlled by {@link lodMultiplier}. Clamped to a
     * minimum of 0.1. Defaults to 5.
     *
     * @type {number}
     */
    set lodBaseDistance(value: number);
    /**
     * Gets the base distance for the first LOD transition.
     *
     * @type {number}
     */
    get lodBaseDistance(): number;
    /**
     * Sets the multiplier between successive LOD distance thresholds. Each LOD level
     * transitions at this factor times the previous level's distance, creating a geometric
     * progression. Lower values keep higher quality at distance; higher values switch to
     * coarser LODs sooner. Clamped to a minimum of 1.2 to avoid degenerate logarithmic LOD
     * computation. LOD distances are automatically compensated for the camera's field of
     * view — a wider FOV makes objects appear smaller on screen, so LOD switches to coarser
     * levels sooner to match the reduced screen-space detail. Defaults to 3.
     *
     * @type {number}
     */
    set lodMultiplier(value: number);
    /**
     * Gets the geometric multiplier between successive LOD distance thresholds.
     *
     * @type {number}
     */
    get lodMultiplier(): number;
    /**
     * @deprecated Use {@link lodBaseDistance} and {@link lodMultiplier} instead.
     * @type {number[]|null}
     */
    set lodDistances(value: number[]);
    /**
     * @deprecated Use {@link lodBaseDistance} and {@link lodMultiplier} instead.
     * @type {number[]}
     */
    get lodDistances(): number[];
    /**
     * @deprecated Use app.scene.gsplat.splatBudget instead for global budget control.
     * @type {number}
     */
    set splatBudget(value: number);
    get splatBudget(): number;
    /**
     * Sets whether to use the unified gsplat rendering. Default is false.
     *
     * Note: Material handling differs between modes. When unified is false, use
     * {@link GSplatComponent#material}. When unified is true, materials are shared per
     * camera/layer - use {@link GSplatComponentSystem#getMaterial} instead.
     *
     * @type {boolean}
     */
    set unified(value: boolean);
    /**
     * Gets whether to use the unified gsplat rendering.
     *
     * @type {boolean}
     * @alpha
     */
    get unified(): boolean;
    /**
     * Gets the unique identifier for this component. This ID is used by the picking system
     * and is also written to the work buffer when `app.scene.gsplat.enableIds` is enabled, making
     * it available to custom shaders for effects like highlighting or animation.
     *
     * @type {number}
     */
    get id(): number;
    /**
     * Sets the work buffer update mode. Only applicable in unified rendering mode.
     *
     * In unified mode, splat data is rendered to a work buffer only when needed (e.g., when
     * transforms change). Can be:
     * - {@link WORKBUFFER_UPDATE_AUTO}: Update only when needed (default).
     * - {@link WORKBUFFER_UPDATE_ONCE}: Force update this frame, then switch to AUTO.
     * - {@link WORKBUFFER_UPDATE_ALWAYS}: Update every frame.
     *
     * This is typically useful when using custom shader code via {@link workBufferModifier} that
     * depends on external factors like time or animated uniforms.
     *
     * Note: {@link WORKBUFFER_UPDATE_ALWAYS} has a performance impact as it re-renders
     * all splat data to the work buffer every frame. Where possible, consider using shader
     * customization on the unified gsplat material (`app.scene.gsplat.material`) which is
     * applied during final rendering without re-rendering the work buffer.
     *
     * @type {number}
     */
    set workBufferUpdate(value: number);
    /**
     * Gets the work buffer update mode.
     *
     * @type {number}
     */
    get workBufferUpdate(): number;
    /**
     * Sets custom shader code for modifying splats when written to the work buffer. Only
     * applicable in unified rendering mode.
     *
     * Must provide all three functions:
     * - `modifySplatCenter`: Modify the splat center position
     * - `modifySplatRotationScale`: Modify the splat rotation and scale
     * - `modifySplatColor`: Modify the splat color
     *
     * Calling this method automatically triggers a work buffer re-render.
     *
     * @param {{ glsl?: string, wgsl?: string }|null} value - The modifier code for GLSL and/or WGSL.
     * @example
     * entity.gsplat.setWorkBufferModifier({
     *     glsl: `
     *         void modifySplatCenter(inout vec3 center) {}
     *         void modifySplatRotationScale(vec3 originalCenter, vec3 modifiedCenter, inout vec4 rotation, inout vec3 scale) {}
     *         void modifySplatColor(vec3 center, inout vec4 color) { color.rgb *= vec3(1.0, 0.0, 0.0); }
     *     `,
     *     wgsl: `
     *         fn modifySplatCenter(center: ptr<function, vec3f>) {}
     *         fn modifySplatRotationScale(originalCenter: vec3f, modifiedCenter: vec3f, rotation: ptr<function, vec4f>, scale: ptr<function, vec3f>) {}
     *         fn modifySplatColor(center: vec3f, color: ptr<function, vec4f>) { (*color).r = 1.0; (*color).g = 0.0; (*color).b = 0.0; }
     *     `
     * });
     */
    setWorkBufferModifier(value: {
        glsl?: string;
        wgsl?: string;
    } | null): void;
    /**
     * 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;
    /**
     * Sets a GSplat resource directly (for procedural/container splats).
     * When set, this takes precedence over the asset property.
     *
     * @type {GSplatResourceBase|null}
     */
    set resource(value: GSplatResourceBase | null);
    /**
     * Gets the GSplat resource. Returns the directly set resource if available,
     * otherwise returns the resource from the assigned asset.
     *
     * @type {GSplatResourceBase|null}
     */
    get resource(): GSplatResourceBase | null;
    /** @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;
    /**
     * Sets a shader parameter for this gsplat instance. Parameters set here are applied
     * during unified rendering.
     *
     * @param {string} name - The name of the parameter (uniform name in shader).
     * @param {number|number[]|ArrayBufferView|Texture|StorageBuffer} data - The value for the parameter.
     */
    setParameter(name: string, data: number | number[] | ArrayBufferView | Texture | StorageBuffer): void;
    /**
     * Gets a shader parameter value previously set with {@link setParameter}.
     *
     * @param {string} name - The name of the parameter.
     * @returns {number|number[]|ArrayBufferView|undefined} The parameter value, or undefined if not set.
     */
    getParameter(name: string): number | number[] | ArrayBufferView | undefined;
    /**
     * Deletes a shader parameter previously set with {@link setParameter}.
     *
     * @param {string} name - The name of the parameter to delete.
     */
    deleteParameter(name: string): void;
    /**
     * Gets an instance texture by name. Instance textures are per-component textures defined
     * in the resource's format with `storage: GSPLAT_STREAM_INSTANCE`. Only available in unified mode.
     *
     * @param {string} name - The name of the texture.
     * @returns {Texture|null} The texture, or null if not found or not in unified mode.
     * @example
     * // Add an instance stream to the resource format
     * resource.format.addExtraStreams([
     *     { name: 'instanceTint', format: pc.PIXELFORMAT_RGBA8, storage: pc.GSPLAT_STREAM_INSTANCE }
     * ]);
     *
     * // Get the instance texture and fill it with data
     * const texture = entity.gsplat.getInstanceTexture('instanceTint');
     * if (texture) {
     *     const data = texture.lock();
     *     // Fill texture data...
     *     texture.unlock();
     * }
     */
    getInstanceTexture(name: string): Texture | null;
    _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 { GSplatResourceBase } from '../../../scene/gsplat/gsplat-resource-base.js';
import type { Texture } from '../../../platform/graphics/texture.js';
import type { StorageBuffer } from '../../../platform/graphics/storage-buffer.js';
import type { GSplatComponentSystem } from './system.js';
import type { Entity } from '../../entity.js';
