import { BindMode, Box3, BufferGeometry, Camera, Color, ColorRepresentation, DataTexture, InstancedBufferAttribute, Material, Matrix4, Mesh, Object3D, Object3DEventMap, Scene, Skeleton, Sphere, Vector3, WebGLProgramParametersWithUniforms, WebGLRenderer } from "three";
import { ColorPartName } from "../../../CharacterModel";
import { CustomSortCallback, OnFrustumEnterCallback } from "./feature/FrustumCulling";
import { Entity } from "./feature/Instances";
import { LODInfo } from "./feature/LOD";
import { InstancedEntity } from "./InstancedEntity";
import { BVHParams, InstancedMeshBVH } from "./InstancedMeshBVH";
import { GLInstancedBufferAttribute } from "./utils/GLInstancedBufferAttribute";
import { SquareDataTexture } from "./utils/SquareDataTexture";
/**
 * Parameters for configuring an `InstancedMesh2` instance.
 */
export interface InstancedMesh2Params {
    /**
     * Determines the maximum number of instances that buffers can hold.
     * The buffers will be expanded automatically if necessary.
     * @default 1000
     */
    capacity?: number;
    /**
     * Determines whether to create an array of `InstancedEntity` to easily manipulate instances at the cost of more memory.
     * @default false
     */
    createEntities?: boolean;
    /**
     * Determines whether `InstancedEntity` can use the `rotation` property.
     * If `true` `quaternion` and `rotation` will be synchronized, affecting performance.
     * @default false
     */
    allowsEuler?: boolean;
    /**
     * WebGL renderer instance.
     * If not provided, buffers will be initialized during the first render, resulting in no instances being rendered initially.
     * @default null
     */
    renderer?: WebGLRenderer;
}
/**
 * Alternative `InstancedMesh` class to support additional features like frustum culling, fast raycasting, LOD and more.
 * @template TData Type for additional instance data.
 * @template TGeometry Type extending `BufferGeometry`.
 * @template TMaterial Type extending `Material` or an array of `Material`.
 * @template TEventMap Type extending `Object3DEventMap`.
 */
export declare class InstancedMesh2<TData = {}, TGeometry extends BufferGeometry = BufferGeometry, TMaterial extends Material | Material[] = Material | Material[], TEventMap extends Object3DEventMap = Object3DEventMap> extends Mesh<TGeometry, TMaterial, TEventMap> {
    /**
     * The number of instances rendered in the last frame.
     */
    count: number;
    /**
     * @defaultValue `InstancedMesh2`
     */
    readonly type = "InstancedMesh2";
    /**
     * Indicates if this is an `InstancedMesh2`.
     */
    readonly isInstancedMesh2 = true;
    /**
     * An array of `Entity` representing individual instances.
     * This array is only initialized if `createEntities` is set to `true` in the constructor parameters.
     */
    instances: Entity<TData>[] | null;
    /**
     * Attribute storing indices of the instances to be rendered.
     */
    instanceIndex: GLInstancedBufferAttribute | null;
    /**
     * Texture storing matrices for instances.
     */
    matricesTexture: SquareDataTexture;
    /**
     * Texture storing colors for instances.
     */
    colorsTexture: SquareDataTexture | null;
    /**
     * Texture storing multiple colors per instance for per-material coloring.
     * Stores 8 colors per instance (hair, shirt_short, shirt_long, pants_short, pants_long, shoes, skin, lips)
     * Each row stores 2 colors (8 floats), so we need 4 pixels per instance (4 * 2 = 8 colors)
     */
    materialColorsTexture: SquareDataTexture | null;
    /**
     * Texture storing morph target influences for instances.
     */
    morphTexture: DataTexture | null;
    /**
     * Texture storing bones for instances.
     */
    boneTexture: SquareDataTexture | null;
    /**
     * Texture storing custom uniforms per instance.
     */
    uniformsTexture: SquareDataTexture | null;
    /**
     * This bounding box encloses all instances, which can be calculated with `computeBoundingBox` method.
     * Bounding box isn't computed by default. It needs to be explicitly computed, otherwise it's `null`.
     */
    boundingBox: Box3 | null;
    /**
     * This bounding sphere encloses all instances, which can be calculated with `computeBoundingSphere` method.
     * Bounding sphere is computed during its first render. You may need to recompute it if an instance is transformed.
     */
    boundingSphere: Sphere | null;
    /**
     * BVH structure for optimized culling and intersection testing.
     * It's possible to create the BVH using the `computeBVH` method. Once created it will be updated automatically.
     */
    bvh: InstancedMeshBVH | null;
    /**
     * Custom sort function for instances.
     * It's possible to create the radix sort using the `createRadixSort` method.
     * @default null
     */
    customSort: CustomSortCallback | null;
    /**
     * Flag indicating if raycasting should only consider the last frame frustum culled instances.
     * This is ignored if the bvh has been created.
     * @default false
     */
    raycastOnlyFrustum: boolean;
    /**
     * Array storing visibility and availability for instances.
     * [visible0, active0, visible1, active1, ...]
     */
    readonly availabilityArray: boolean[];
    /**
     * Contains data for managing LOD, allowing different levels of detail for rendering and shadow casting.
     */
    LODinfo: LODInfo<TData> | null;
    /**
     * Flag indicating whether to automatically perform frustum culling before rendering.
     * @default true
     */
    autoUpdate: boolean;
    /**
     * Either `AttachedBindMode` or `DetachedBindMode`. `AttachedBindMode` means the skinned mesh shares the same world space as the skeleton.
     * This is not true when using `DetachedBindMode` which is useful when sharing a skeleton across multiple skinned meshes.
     * @default `AttachedBindMode`
     */
    bindMode: BindMode;
    /**
     * The base matrix that is used for the bound bone transforms.
     */
    bindMatrix: Matrix4 | null;
    /**
     * The base matrix that is used for resetting the bound bone transforms.
     */
    bindMatrixInverse: Matrix4 | null;
    /**
     * Skeleton representing the bone hierarchy of the skinned mesh.
     */
    skeleton: Skeleton | null;
    /**
     * Callback function called if an instance is inside the frustum.
     */
    onFrustumEnter: OnFrustumEnterCallback | null;
    /** @internal */ _renderer: WebGLRenderer | null;
    /** @internal */ _instancesCount: number;
    /** @internal */ _instancesArrayCount: number;
    /** @internal */ _perObjectFrustumCulled: boolean;
    /** @internal */ _sortObjects: boolean;
    /** @internal */ _capacity: number;
    /** @internal */ _indexArrayNeedsUpdate: boolean;
    /** @internal */ _geometry: TGeometry;
    /** @internal */ _parentLOD: InstancedMesh2;
    protected readonly _allowsEuler: boolean;
    protected readonly _tempInstance: InstancedEntity;
    protected _useOpacity: boolean;
    protected _currentMaterial: Material | null;
    protected _customProgramCacheKeyBase: (() => string) | null;
    protected _onBeforeCompileBase: ((parameters: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer) => void) | null;
    protected _propertiesGetBase: ((obj: unknown) => unknown) | null;
    protected _propertiesGetMap: WeakMap<Material, (obj: unknown) => unknown>;
    protected _properties: WeakMap<Material, unknown>;
    protected _freeIds: number[];
    protected _createEntities: boolean;
    /** @internal */ isInstancedMesh: boolean;
    /** @internal */ instanceMatrix: InstancedBufferAttribute;
    /** @internal */ instanceColor: null;
    /**
     * The capacity of the instance buffers.
     */
    get capacity(): number;
    /**
     * The number of active instances.
     */
    get instancesCount(): number;
    /**
     * Determines if per-instance frustum culling is enabled.
     * @default true
     */
    get perObjectFrustumCulled(): boolean;
    set perObjectFrustumCulled(value: boolean);
    /**
     * Determines if objects should be sorted before rendering.
     * @default false
     */
    get sortObjects(): boolean;
    set sortObjects(value: boolean);
    /**
     * An instance of `BufferGeometry` (or derived classes), defining the object's structure.
     */
    get geometry(): TGeometry;
    set geometry(value: TGeometry);
    /** @internal */
    constructor(geometry: TGeometry, material: TMaterial, params?: InstancedMesh2Params, LOD?: InstancedMesh2);
    constructor(geometry: TGeometry, material: TMaterial, params?: InstancedMesh2Params);
    onBeforeShadow(renderer: WebGLRenderer, scene: Scene, camera: Camera, shadowCamera: Camera, geometry: BufferGeometry, depthMaterial: Material, group: any): void;
    onBeforeRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, material: Material, group: any): void;
    onAfterShadow(renderer: WebGLRenderer, scene: Scene, camera: Camera, shadowCamera: Camera, geometry: BufferGeometry, depthMaterial: Material, group: any): void;
    onAfterRender(renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, material: Material, group: any): void;
    protected isFirstGroup(materialIndex: number): boolean;
    protected isLastGroup(materialIndex: number): boolean;
    protected initIndexAttribute(): void;
    protected initMatricesTexture(): void;
    protected initColorsTexture(): void;
    protected initMaterialColorsTexture(): void;
    materialsNeedsUpdate(): void;
    protected patchGeometry(geometry: TGeometry): void;
    protected _customProgramCacheKey: () => string;
    protected _onBeforeCompile: (shader: WebGLProgramParametersWithUniforms, renderer: WebGLRenderer) => void;
    protected patchMaterial(renderer: WebGLRenderer, material: Material): void;
    protected unpatchMaterial(renderer: WebGLRenderer, material: Material): void;
    /**
     * Creates and computes the BVH (Bounding Volume Hierarchy) for the instances.
     * It's recommended to create it when all the instance matrices have been assigned.
     * Once created it will be updated automatically.
     * @param config Optional configuration parameters object. See `BVHParams` for details.
     */
    computeBVH(config?: BVHParams): void;
    /**
     * Disposes of the BVH structure.
     */
    disposeBVH(): void;
    /**
     * Sets the local transformation matrix for a specific instance.
     * @param id The index of the instance.
     * @param matrix A `Matrix4` representing the local transformation to apply to the instance.
     */
    setMatrixAt(id: number, matrix: Matrix4): void;
    /**
     * Gets the local transformation matrix of a specific instance.
     * @param id The index of the instance.
     * @param matrix Optional `Matrix4` to store the result.
     * @returns The transformation matrix of the instance.
     */
    getMatrixAt(id: number, matrix?: Matrix4): Matrix4;
    /**
     * Retrieves the position of a specific instance.
     * @param index The index of the instance.
     * @param target Optional `Vector3` to store the result.
     * @returns The position of the instance as a `Vector3`.
     */
    getPositionAt(index: number, target?: Vector3): Vector3;
    /** @internal */
    getPositionAndMaxScaleOnAxisAt(index: number, position: Vector3): number;
    /** @internal */
    applyMatrixAtToSphere(index: number, sphere: Sphere, center: Vector3, radius: number): void;
    /**
     * Sets the visibility of a specific instance.
     * @param id The index of the instance.
     * @param visible Whether the instance should be visible.
     */
    setVisibilityAt(id: number, visible: boolean): void;
    /**
     * Gets the visibility of a specific instance.
     * @param id The index of the instance.
     * @returns Whether the instance is visible.
     */
    getVisibilityAt(id: number): boolean;
    /**
     * Sets the availability of a specific instance.
     * @param id The index of the instance.
     * @param active Whether the instance is active (not deleted).
     */
    setActiveAt(id: number, active: boolean): void;
    /**
     * Gets the availability of a specific instance.
     * @param id The index of the instance.
     * @returns Whether the instance is active (not deleted).
     */
    getActiveAt(id: number): boolean;
    /**
     * Indicates if a specific instance is visible and active.
     * @param id The index of the instance.
     * @returns Whether the instance is visible and active.
     */
    getActiveAndVisibilityAt(id: number): boolean;
    /**
     * Set if a specific instance is visible and active.
     * @param id The index of the instance.
     * @param value Whether the instance is active and active (not deleted).
     */
    setActiveAndVisibilityAt(id: number, value: boolean): void;
    /**
     * Sets the color of a specific instance.
     * @param id The index of the instance.
     * @param color The color to assign to the instance.
     */
    setColorAt(id: number, color: ColorRepresentation): void;
    /**
     * Gets the color of a specific instance.
     * @param id The index of the instance.
     * @param color Optional `Color` to store the result.
     * @returns The color of the instance.
     */
    getColorAt(id: number, color?: Color): Color;
    /**
     * Sets the opacity of a specific instance.
     * @param id The index of the instance.
     * @param value The opacity value to assign.
     */
    setOpacityAt(id: number, value: number): void;
    /**
     * Gets the opacity of a specific instance.
     * @param id The index of the instance.
     * @returns The opacity of the instance.
     */
    getOpacityAt(id: number): number;
    /**
     * Sets material-specific colors for an instance.
     * @param id The index of the instance.
     * @param materialColors Object containing colors for different materials.
     */
    setMaterialColorsAt(id: number, materialColors: Map<ColorPartName, Color>): void;
    /**
     * Gets material-specific colors for an instance.
     * @param id The index of the instance.
     * @returns Object containing colors for different materials.
     */
    getMaterialColorsAt(id: number): {
        hair: Color;
        shirt_short: Color;
        shirt_long: Color;
        pants_short: Color;
        pants_long: Color;
        shoes: Color;
        skin: Color;
        lips: Color;
    } | null;
    /**
     * Copies `position`, `quaternion`, and `scale` of a specific instance to the specified target `Object3D`.
     * @param id The index of the instance.
     * @param target The `Object3D` where to copy transformation data.
     */
    copyTo(id: number, target: Object3D): void;
    /**
     * Computes the bounding box that encloses all instances, and updates the `boundingBox` attribute.
     */
    computeBoundingBox(): void;
    /**
     * Computes the bounding sphere that encloses all instances, and updates the `boundingSphere` attribute.
     */
    computeBoundingSphere(): void;
    clone(recursive?: boolean): this;
    copy(argSource: Object3D, recursive?: boolean): this;
    /**
     * Frees the GPU-related resources allocated.
     */
    dispose(): void;
    updateMatrixWorld(force?: boolean): void;
}
