/** This file must only contain pure code and pure imports */
import { type FloatArray, type IndicesArray, type Nullable } from "../types.js";
import { Matrix } from "../Maths/math.vector.pure.js";
import { type Vector3 } from "../Maths/math.vector.js";
import { type Camera } from "../Cameras/camera.pure.js";
import { type Node } from "../node.js";
import { AbstractMesh } from "../Meshes/abstractMesh.pure.js";
import { type IMeshDataOptions } from "../Meshes/abstractMesh.js";
import { Mesh } from "../Meshes/mesh.pure.js";
import { type Material } from "../Materials/material.pure.js";
import { type Skeleton } from "../Bones/skeleton.js";
import { TransformNode } from "./transformNode.pure.js";
import { type Light } from "../Lights/light.js";
import { VertexBuffer } from "../Buffers/buffer.pure.js";
import { type Geometry } from "./geometry.js";
/**
 * Creates an instance based on a source mesh.
 */
export declare class InstancedMesh extends AbstractMesh {
    private _sourceMesh;
    private _currentLOD;
    private _billboardWorldMatrix;
    /** @internal */
    _indexInSourceMeshInstanceArray: number;
    /** @internal */
    _distanceToCamera: number;
    /** @internal */
    _previousWorldMatrix: Nullable<Matrix>;
    /**
     * Creates a new InstancedMesh object from the mesh source.
     * @param name defines the name of the instance
     * @param source the mesh to create the instance from
     */
    constructor(name: string, source: Mesh);
    /**
     * @returns the string "InstancedMesh".
     */
    getClassName(): string;
    /** Gets the list of lights affecting that mesh */
    get lightSources(): Light[];
    /** @internal */
    _resyncLightSources(): void;
    /** @internal */
    _resyncLightSource(): void;
    /** @internal */
    _removeLightSource(): void;
    /**
     * If the source mesh receives shadows
     */
    get receiveShadows(): boolean;
    set receiveShadows(_value: boolean);
    /**
     * The material of the source mesh
     */
    get material(): Nullable<Material>;
    set material(_value: Nullable<Material>);
    /**
     * Visibility of the source mesh
     */
    get visibility(): number;
    set visibility(_value: number);
    /**
     * Skeleton of the source mesh
     */
    get skeleton(): Nullable<Skeleton>;
    set skeleton(_value: Nullable<Skeleton>);
    /**
     * Rendering ground id of the source mesh
     */
    get renderingGroupId(): number;
    set renderingGroupId(value: number);
    /**
     * @returns the total number of vertices (integer).
     */
    getTotalVertices(): number;
    /**
     * Returns a positive integer : the total number of indices in this mesh geometry.
     * @returns the number of indices or zero if the mesh has no geometry.
     */
    getTotalIndices(): number;
    /**
     * The source mesh of the instance
     */
    get sourceMesh(): Mesh;
    /**
     * Gets the mesh internal Geometry object
     */
    get geometry(): Nullable<Geometry>;
    /**
     * Creates a new InstancedMesh object from the mesh model.
     * @see https://doc.babylonjs.com/features/featuresDeepDive/mesh/copies/instances
     * @param name defines the name of the new instance
     * @returns a new InstancedMesh
     */
    createInstance(name: string): InstancedMesh;
    /**
     * Is this node ready to be used/rendered
     * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
     * @returns is it ready
     */
    isReady(completeCheck?: boolean): boolean;
    /**
     * Returns an array of integers or a typed array (Int32Array, Uint32Array, Uint16Array) populated with the mesh indices.
     * @param kind kind of verticies to retrieve (eg. positions, normals, uvs, etc.)
     * @param copyWhenShared If true (default false) and and if the mesh geometry is shared among some other meshes, the returned array is a copy of the internal one.
     * @param forceCopy defines a boolean forcing the copy of the buffer no matter what the value of copyWhenShared is
     * @returns a float array or a Float32Array of the requested kind of data : positions, normals, uvs, etc.
     */
    getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray>;
    /** @internal */
    copyVerticesData(kind: string, vertexData: {
        [kind: string]: Float32Array;
    }): void;
    /** @internal */
    getVertexBuffer(kind: string, bypassInstanceData?: boolean): Nullable<VertexBuffer>;
    /**
     * Sets the vertex data of the mesh geometry for the requested `kind`.
     * If the mesh has no geometry, a new Geometry object is set to the mesh and then passed this vertex data.
     * The `data` are either a numeric array either a Float32Array.
     * The parameter `updatable` is passed as is to the underlying Geometry object constructor (if initially none) or updater.
     * The parameter `stride` is an optional positive integer, it is usually automatically deducted from the `kind` (3 for positions or normals, 2 for UV, etc).
     * Note that a new underlying VertexBuffer object is created each call.
     * If the `kind` is the `PositionKind`, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
     *
     * Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     *
     * Returns the Mesh.
     * @param kind defines vertex data kind
     * @param data defines the data source
     * @param updatable defines if the data must be flagged as updatable (false as default)
     * @param stride defines the vertex stride (optional)
     * @returns the current mesh
     */
    setVerticesData(kind: string, data: FloatArray, updatable?: boolean, stride?: number): AbstractMesh;
    /**
     * Updates the existing vertex data of the mesh geometry for the requested `kind`.
     * If the mesh has no geometry, it is simply returned as it is.
     * The `data` are either a numeric array either a Float32Array.
     * No new underlying VertexBuffer object is created.
     * If the `kind` is the `PositionKind` and if `updateExtends` is true, the mesh BoundingInfo is renewed, so the bounding box and sphere, and the mesh World Matrix is recomputed.
     * If the parameter `makeItUnique` is true, a new global geometry is created from this positions and is set to the mesh.
     *
     * Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     *
     * Returns the Mesh.
     * @param kind defines vertex data kind
     * @param data defines the data source
     * @param updateExtends defines if extends info of the mesh must be updated (can be null). This is mostly useful for "position" kind
     * @param makeItUnique defines it the updated vertex buffer must be flagged as unique (false by default)
     * @returns the source mesh
     */
    updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean, makeItUnique?: boolean): Mesh;
    /**
     * Sets the mesh indices.
     * Expects an array populated with integers or a typed array (Int32Array, Uint32Array, Uint16Array).
     * If the mesh has no geometry, a new Geometry object is created and set to the mesh.
     * This method creates a new index buffer each call.
     * Returns the Mesh.
     * @param indices the source data
     * @param totalVertices defines the total number of vertices referenced by indices (could be null)
     * @returns source mesh
     */
    setIndices(indices: IndicesArray, totalVertices?: Nullable<number>): Mesh;
    /**
     * Boolean : True if the mesh owns the requested kind of data.
     * @param kind defines which buffer to check (positions, indices, normals, etc). Possible `kind` values :
     * - VertexBuffer.PositionKind
     * - VertexBuffer.UVKind
     * - VertexBuffer.UV2Kind
     * - VertexBuffer.UV3Kind
     * - VertexBuffer.UV4Kind
     * - VertexBuffer.UV5Kind
     * - VertexBuffer.UV6Kind
     * - VertexBuffer.ColorKind
     * - VertexBuffer.MatricesIndicesKind
     * - VertexBuffer.MatricesIndicesExtraKind
     * - VertexBuffer.MatricesWeightsKind
     * - VertexBuffer.MatricesWeightsExtraKind
     * @returns true if data kind is present
     */
    isVerticesDataPresent(kind: string): boolean;
    /**
     * @returns an array of indices (IndicesArray).
     */
    getIndices(): Nullable<IndicesArray>;
    /** @internal */
    get _positions(): Nullable<Vector3[]>;
    /** @internal */
    refreshBoundingInfo(applySkeletonOrOptions?: boolean | IMeshDataOptions, applyMorph?: boolean): InstancedMesh;
    /** @internal */
    _preActivate(): InstancedMesh;
    /**
     * @internal
     */
    _activate(renderId: number, intermediateRendering: boolean): boolean;
    /** @internal */
    _postActivate(): void;
    /** @internal */
    getWorldMatrix(): Matrix;
    /** @internal */
    get isAnInstance(): boolean;
    /**
     * Returns the current associated LOD AbstractMesh.
     * @param camera defines the camera to use to pick the LOD level
     * @returns a Mesh or `null` if no LOD is associated with the AbstractMesh
     */
    getLOD(camera: Camera): AbstractMesh;
    /**
     * @internal
     */
    _preActivateForIntermediateRendering(renderId: number): Mesh;
    /** @internal */
    _syncSubMeshes(): InstancedMesh;
    /** @internal */
    _generatePointsArray(): boolean;
    /** @internal */
    _updateBoundingInfo(): AbstractMesh;
    /**
     * Creates a new InstancedMesh from the current mesh.
     *
     * Returns the clone.
     * @param name the cloned mesh name
     * @param newParent the optional Node to parent the clone to.
     * @param doNotCloneChildren if `true` the model children aren't cloned.
     * @param newSourceMesh if set this mesh will be used as the source mesh instead of ths instance's one
     * @returns the clone
     */
    clone(name: string, newParent?: Nullable<Node>, doNotCloneChildren?: boolean, newSourceMesh?: Mesh): InstancedMesh;
    /**
     * Disposes the InstancedMesh.
     * Returns nothing.
     * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
     * @param disposeMaterialAndTextures Set to true to also dispose referenced materials and textures (false by default)
     */
    dispose(doNotRecurse?: boolean, disposeMaterialAndTextures?: boolean): void;
    /**
     * @internal
     */
    _serializeAsParent(serializationObject: any): void;
    /**
     * Instantiate (when possible) or clone that node with its hierarchy
     * @param newParent defines the new parent to use for the instance (or clone)
     * @param options defines options to configure how copy is done
     * @param onNewNodeCreated defines an option callback to call when a clone or an instance is created
     * @returns an instance (or a clone) of the current node with its hierarchy
     */
    instantiateHierarchy(newParent?: Nullable<TransformNode>, options?: {
        doNotInstantiate: boolean | ((node: TransformNode) => boolean);
        newSourcedMesh?: Mesh;
    }, onNewNodeCreated?: (source: TransformNode, clone: TransformNode) => void): Nullable<TransformNode>;
}
/**
 * Register side effects for instancedMesh.
 * Safe to call multiple times; only the first call has an effect.
 */
export declare function RegisterInstancedMesh(): void;
