import type { Nullable, FloatArray, DataArray, IndicesArray } from "../types";
import type { Scene } from "../scene";
import type { Vector2 } from "../Maths/math.vector";
import { Vector3 } from "../Maths/math.vector";
import type { IGetSetVerticesData } from "../Meshes/mesh.vertexData";
import { VertexData } from "../Meshes/mesh.vertexData";
import { VertexBuffer } from "../Buffers/buffer";
import type { Effect } from "../Materials/effect";
import { BoundingInfo } from "../Culling/boundingInfo";
import type { DataBuffer } from "../Buffers/dataBuffer";
import type { Mesh } from "../Meshes/mesh";
import type { AbstractEngine } from "../Engines/abstractEngine";
import type { IAssetContainer } from "../IAssetContainer.js";
/**
 * Class used to store geometry data (vertex buffers + index buffer)
 */
export declare class Geometry implements IGetSetVerticesData {
    /**
     * Gets or sets the ID of the geometry
     */
    id: string;
    /**
     * Gets or sets the unique ID of the geometry
     */
    uniqueId: number;
    /**
     * Gets the delay loading state of the geometry (none by default which means not delayed)
     */
    delayLoadState: number;
    /**
     * Gets the file containing the data to load when running in delay load state
     */
    delayLoadingFile: Nullable<string>;
    /**
     * Callback called when the geometry is updated
     */
    onGeometryUpdated: (geometry: Geometry, kind?: string) => void;
    private _scene;
    private _engine;
    private _meshes;
    private _totalVertices;
    private _totalIndices?;
    /** @internal */
    _loadedUniqueId: string;
    /** @internal */
    _indices: IndicesArray;
    /** @internal */
    _vertexBuffers: {
        [key: string]: VertexBuffer;
    };
    private _isDisposed;
    private _extend;
    private _boundingBias;
    /** @internal */
    _delayInfo: Array<string>;
    private _indexBuffer;
    private _indexBufferIsUpdatable;
    /** @internal */
    _boundingInfo: Nullable<BoundingInfo>;
    /** @internal */
    _delayLoadingFunction: Nullable<(any: any, geometry: Geometry) => void>;
    /** @internal */
    _softwareSkinningFrameId: number;
    private _vertexArrayObjects;
    private _updatable;
    /** @internal */
    _positions: Nullable<Vector3[]>;
    private _positionsCache;
    /** @internal */
    _parentContainer: Nullable<IAssetContainer>;
    /**
     *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y
     */
    get boundingBias(): Vector2;
    /**
     *  Gets or sets the Bias Vector to apply on the bounding elements (box/sphere), the max extend is computed as v += v * bias.x + bias.y, the min is computed as v -= v * bias.x + bias.y
     */
    set boundingBias(value: Vector2);
    /**
     * Static function used to attach a new empty geometry to a mesh
     * @param mesh defines the mesh to attach the geometry to
     * @returns the new Geometry
     */
    static CreateGeometryForMesh(mesh: Mesh): Geometry;
    /** Get the list of meshes using this geometry */
    get meshes(): Mesh[];
    /**
     * If set to true (false by default), the bounding info applied to the meshes sharing this geometry will be the bounding info defined at the class level
     * and won't be computed based on the vertex positions (which is what we get when useBoundingInfoFromGeometry = false)
     */
    useBoundingInfoFromGeometry: boolean;
    /**
     * Creates a new geometry
     * @param id defines the unique ID
     * @param scene defines the hosting scene
     * @param vertexData defines the VertexData used to get geometry data
     * @param updatable defines if geometry must be updatable (false by default)
     * @param mesh defines the mesh that will be associated with the geometry
     */
    constructor(id: string, scene?: Scene, vertexData?: VertexData, updatable?: boolean, mesh?: Nullable<Mesh>);
    /**
     * Gets the current extend of the geometry
     */
    get extend(): {
        minimum: Vector3;
        maximum: Vector3;
    };
    /**
     * Gets the hosting scene
     * @returns the hosting Scene
     */
    getScene(): Scene;
    /**
     * Gets the hosting engine
     * @returns the hosting Engine
     */
    getEngine(): AbstractEngine;
    /**
     * Defines if the geometry is ready to use
     * @returns true if the geometry is ready to be used
     */
    isReady(): boolean;
    /**
     * Gets a value indicating that the geometry should not be serialized
     */
    get doNotSerialize(): boolean;
    /** @internal */
    _rebuild(): void;
    /**
     * Affects all geometry data in one call
     * @param vertexData defines the geometry data
     * @param updatable defines if the geometry must be flagged as updatable (false as default)
     */
    setAllVerticesData(vertexData: VertexData, updatable?: boolean): void;
    /**
     * Set specific vertex data
     * @param kind defines the data kind (Position, normal, etc...)
     * @param data defines the vertex data to use
     * @param updatable defines if the vertex must be flagged as updatable (false as default)
     * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified
     */
    setVerticesData(kind: string, data: FloatArray, updatable?: boolean, stride?: number): void;
    /**
     * Removes a specific vertex data
     * @param kind defines the data kind (Position, normal, etc...)
     */
    removeVerticesData(kind: string): void;
    /**
     * Affect a vertex buffer to the geometry. the vertexBuffer.getKind() function is used to determine where to store the data
     * @param buffer defines the vertex buffer to use
     * @param totalVertices defines the total number of vertices for position kind (could be null)
     * @param disposeExistingBuffer disposes the existing buffer, if any (default: true)
     */
    setVerticesBuffer(buffer: VertexBuffer, totalVertices?: Nullable<number>, disposeExistingBuffer?: boolean): void;
    /**
     * Update a specific vertex buffer
     * This function will directly update the underlying DataBuffer according to the passed numeric array or Float32Array
     * It will do nothing if the buffer is not updatable
     * @param kind defines the data kind (Position, normal, etc...)
     * @param data defines the data to use
     * @param offset defines the offset in the target buffer where to store the data
     * @param useBytes set to true if the offset is in bytes
     */
    updateVerticesDataDirectly(kind: string, data: DataArray, offset: number, useBytes?: boolean): void;
    /**
     * Update a specific vertex buffer
     * This function will create a new buffer if the current one is not updatable
     * @param kind defines the data kind (Position, normal, etc...)
     * @param data defines the data to use
     * @param updateExtends defines if the geometry extends must be recomputed (false by default)
     */
    updateVerticesData(kind: string, data: FloatArray, updateExtends?: boolean): void;
    private _updateBoundingInfo;
    /**
     * @internal
     */
    _bind(effect: Nullable<Effect>, indexToBind?: Nullable<DataBuffer>, overrideVertexBuffers?: {
        [kind: string]: Nullable<VertexBuffer>;
    }, overrideVertexArrayObjects?: {
        [key: string]: WebGLVertexArrayObject;
    }): void;
    /**
     * Gets total number of vertices
     * @returns the total number of vertices
     */
    getTotalVertices(): number;
    /**
     * Gets a specific vertex data attached to this geometry. Float data is constructed if the vertex buffer data cannot be returned directly.
     * @param kind defines the data kind (Position, normal, etc...)
     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
     * @returns a float array containing vertex data
     */
    getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray>;
    /**
     * Copies the requested vertex data kind into the given vertex data map. Float data is constructed if the map doesn't have the data.
     * @param kind defines the data kind (Position, normal, etc...)
     * @param vertexData defines the map that stores the resulting data
     */
    copyVerticesData(kind: string, vertexData: {
        [kind: string]: Float32Array;
    }): void;
    /**
     * Returns a boolean defining if the vertex data for the requested `kind` is updatable
     * @param kind defines the data kind (Position, normal, etc...)
     * @returns true if the vertex buffer with the specified kind is updatable
     */
    isVertexBufferUpdatable(kind: string): boolean;
    /**
     * Gets a specific vertex buffer
     * @param kind defines the data kind (Position, normal, etc...)
     * @returns a VertexBuffer
     */
    getVertexBuffer(kind: string): Nullable<VertexBuffer>;
    /**
     * Returns all vertex buffers
     * @returns an object holding all vertex buffers indexed by kind
     */
    getVertexBuffers(): Nullable<{
        [key: string]: VertexBuffer;
    }>;
    /**
     * Gets a boolean indicating if specific vertex buffer is present
     * @param kind defines the data kind (Position, normal, etc...)
     * @returns true if data is present
     */
    isVerticesDataPresent(kind: string): boolean;
    /**
     * Gets a list of all attached data kinds (Position, normal, etc...)
     * @returns a list of string containing all kinds
     */
    getVerticesDataKinds(): string[];
    /**
     * Update index buffer
     * @param indices defines the indices to store in the index buffer
     * @param offset defines the offset in the target buffer where to store the data
     * @param gpuMemoryOnly defines a boolean indicating that only the GPU memory must be updated leaving the CPU version of the indices unchanged (false by default)
     */
    updateIndices(indices: IndicesArray, offset?: number, gpuMemoryOnly?: boolean): void;
    /**
     * Sets the index buffer for this geometry.
     * @param indexBuffer Defines the index buffer to use for this geometry
     * @param totalVertices Defines the total number of vertices used by the buffer
     * @param totalIndices Defines the total number of indices in the index buffer
     * @param is32Bits Defines if the indices are 32 bits. If null (default), the value is guessed from the number of vertices
     */
    setIndexBuffer(indexBuffer: DataBuffer, totalVertices: number, totalIndices: number, is32Bits?: Nullable<boolean>): void;
    /**
     * Creates a new index buffer
     * @param indices defines the indices to store in the index buffer
     * @param totalVertices defines the total number of vertices (could be null)
     * @param updatable defines if the index buffer must be flagged as updatable (false by default)
     * @param dontForceSubMeshRecreation defines a boolean indicating that we don't want to force the recreation of sub-meshes if we don't have to (false by default)
     */
    setIndices(indices: IndicesArray, totalVertices?: Nullable<number>, updatable?: boolean, dontForceSubMeshRecreation?: boolean): void;
    /**
     * Return the total number of indices
     * @returns the total number of indices
     */
    getTotalIndices(): number;
    /**
     * Gets the index buffer array
     * @param copyWhenShared defines if the returned array must be cloned upon returning it if the current geometry is shared between multiple meshes
     * @param forceCopy defines a boolean indicating that the returned array must be cloned upon returning it
     * @returns the index buffer array
     */
    getIndices(copyWhenShared?: boolean, forceCopy?: boolean): Nullable<IndicesArray>;
    /**
     * Gets the index buffer
     * @returns the index buffer
     */
    getIndexBuffer(): Nullable<DataBuffer>;
    /**
     * @internal
     */
    _releaseVertexArrayObject(effect?: Nullable<Effect>): void;
    /**
     * Release the associated resources for a specific mesh
     * @param mesh defines the source mesh
     * @param shouldDispose defines if the geometry must be disposed if there is no more mesh pointing to it
     */
    releaseForMesh(mesh: Mesh, shouldDispose?: boolean): void;
    /**
     * Apply current geometry to a given mesh
     * @param mesh defines the mesh to apply geometry to
     */
    applyToMesh(mesh: Mesh): void;
    private _updateExtend;
    private _applyToMesh;
    private _notifyUpdate;
    /**
     * Load the geometry if it was flagged as delay loaded
     * @param scene defines the hosting scene
     * @param onLoaded defines a callback called when the geometry is loaded
     */
    load(scene: Scene, onLoaded?: () => void): void;
    private _queueLoad;
    /**
     * Invert the geometry to move from a right handed system to a left handed one.
     */
    toLeftHanded(): void;
    /** @internal */
    _resetPointsArrayCache(): void;
    /** @internal */
    _generatePointsArray(): boolean;
    /**
     * Gets a value indicating if the geometry is disposed
     * @returns true if the geometry was disposed
     */
    isDisposed(): boolean;
    private _disposeVertexArrayObjects;
    /**
     * Free all associated resources
     */
    dispose(): void;
    /**
     * Clone the current geometry into a new geometry
     * @param id defines the unique ID of the new geometry
     * @returns a new geometry object
     */
    copy(id: string): Geometry;
    /**
     * Serialize the current geometry info (and not the vertices data) into a JSON object
     * @returns a JSON representation of the current geometry data (without the vertices data)
     */
    serialize(): any;
    private _toNumberArray;
    /**
     * Release any memory retained by the cached data on the Geometry.
     *
     * Call this function to reduce memory footprint of the mesh.
     * Vertex buffers will not store CPU data anymore (this will prevent picking, collisions or physics to work correctly)
     */
    clearCachedData(): void;
    /**
     * Serialize all vertices data into a JSON object
     * @returns a JSON representation of the current geometry data
     */
    serializeVerticeData(): any;
    /**
     * Extracts a clone of a mesh geometry
     * @param mesh defines the source mesh
     * @param id defines the unique ID of the new geometry object
     * @returns the new geometry object
     */
    static ExtractFromMesh(mesh: Mesh, id: string): Nullable<Geometry>;
    /**
     * You should now use Tools.RandomId(), this method is still here for legacy reasons.
     * Implementation from http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#answer-2117523
     * Be aware Math.random() could cause collisions, but:
     * "All but 6 of the 128 bits of the ID are randomly generated, which means that for any two ids, there's a 1 in 2^^122 (or 5.3x10^^36) chance they'll collide"
     * @returns a string containing a new GUID
     */
    static RandomId(): string;
    private static _GetGeometryByLoadedUniqueId;
    /**
     * @internal
     */
    static _ImportGeometry(parsedGeometry: any, mesh: Mesh): void;
    private static _CleanMatricesWeights;
    /**
     * Create a new geometry from persisted data (Using .babylon file format)
     * @param parsedVertexData defines the persisted data
     * @param scene defines the hosting scene
     * @param rootUrl defines the root url to use to load assets (like delayed data)
     * @returns the new geometry object
     */
    static Parse(parsedVertexData: any, scene: Scene, rootUrl: string): Nullable<Geometry>;
}
