import { type Nullable, type IndicesArray, type FloatArray } from "../../types.js";
import { type Matrix, Vector3, Quaternion } from "../../Maths/math.vector.js";
import { type TransformNode } from "../../Meshes/transformNode.js";
import { AbstractMesh } from "../../Meshes/abstractMesh.js";
import { type Scene } from "../../scene.js";
import { type Bone } from "../../Bones/bone.js";
import { type BoundingInfo } from "../../Culling/boundingInfo.js";
import { type PhysicsJointData, PhysicsJoint } from "./physicsJoint.js";
import { Space } from "../../Maths/math.axis.js";
/**
 * The interface for the physics imposter parameters
 * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine
 */
export interface PhysicsImpostorParameters {
    /**
     * The mass of the physics imposter
     */
    mass: number;
    /**
     * The friction of the physics imposter
     */
    friction?: number;
    /**
     * The coefficient of restitution of the physics imposter
     */
    restitution?: number;
    /**
     * The native options of the physics imposter
     */
    nativeOptions?: any;
    /**
     * Specifies if the parent should be ignored
     */
    ignoreParent?: boolean;
    /**
     * Specifies if bi-directional transformations should be disabled
     */
    disableBidirectionalTransformation?: boolean;
    /**
     * The pressure inside the physics imposter, soft object only
     */
    pressure?: number;
    /**
     * The stiffness the physics imposter, soft object only
     */
    stiffness?: number;
    /**
     * The number of iterations used in maintaining consistent vertex velocities, soft object only
     */
    velocityIterations?: number;
    /**
     * The number of iterations used in maintaining consistent vertex positions, soft object only
     */
    positionIterations?: number;
    /**
     * The number used to fix points on a cloth (0, 1, 2, 4, 8) or rope (0, 1, 2) only
     * 0 None, 1, back left or top, 2, back right or bottom, 4, front left, 8, front right
     * Add to fix multiple points
     */
    fixedPoints?: number;
    /**
     * The collision margin around a soft object
     */
    margin?: number;
    /**
     * The collision margin around a soft object
     */
    damping?: number;
    /**
     * The path for a rope based on an extrusion
     */
    path?: any;
    /**
     * The shape of an extrusion used for a rope based on an extrusion
     */
    shape?: any;
}
/**
 * Interface for a physics-enabled object
 * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine
 */
export interface IPhysicsEnabledObject {
    /**
     * The position of the physics-enabled object
     */
    position: Vector3;
    /**
     * The rotation of the physics-enabled object
     */
    rotationQuaternion: Nullable<Quaternion>;
    /**
     * The scale of the physics-enabled object
     */
    scaling: Vector3;
    /**
     * The rotation of the physics-enabled object
     */
    rotation?: Vector3;
    /**
     * The parent of the physics-enabled object
     */
    parent?: any;
    /**
     * The bounding info of the physics-enabled object
     * @returns The bounding info of the physics-enabled object
     */
    getBoundingInfo(): BoundingInfo;
    /**
     * Computes the world matrix
     * @param force Specifies if the world matrix should be computed by force
     * @returns A world matrix
     */
    computeWorldMatrix(force: boolean): Matrix;
    /**
     * Gets the world matrix
     * @returns A world matrix
     */
    getWorldMatrix?(): Matrix;
    /**
     * Gets the child meshes
     * @param directDescendantsOnly Specifies if only direct-descendants should be obtained
     * @returns An array of abstract meshes
     */
    getChildMeshes?(directDescendantsOnly?: boolean): Array<AbstractMesh>;
    /**
     * Gets the vertex data
     * @param kind The type of vertex data
     * @returns A nullable array of numbers, or a float32 array
     */
    getVerticesData(kind: string): Nullable<FloatArray>;
    /**
     * Gets the indices from the mesh
     * @returns A nullable array of index arrays
     */
    getIndices?(): Nullable<IndicesArray>;
    /**
     * Gets the scene from the mesh
     * @returns the indices array or null
     */
    getScene?(): Scene;
    /**
     * Gets the absolute position from the mesh
     * @returns the absolute position
     */
    getAbsolutePosition(): Vector3;
    /**
     * Gets the absolute pivot point from the mesh
     * @returns the absolute pivot point
     */
    getAbsolutePivotPoint(): Vector3;
    /**
     * Rotates the mesh
     * @param axis The axis of rotation
     * @param amount The amount of rotation
     * @param space The space of the rotation
     * @returns The rotation transform node
     */
    rotate(axis: Vector3, amount: number, space?: Space): TransformNode;
    /**
     * Translates the mesh
     * @param axis The axis of translation
     * @param distance The distance of translation
     * @param space The space of the translation
     * @returns The transform node
     */
    translate(axis: Vector3, distance: number, space?: Space): TransformNode;
    /**
     * Sets the absolute position of the mesh
     * @param absolutePosition The absolute position of the mesh
     * @returns The transform node
     */
    setAbsolutePosition(absolutePosition: Vector3): TransformNode;
    /**
     * Gets the class name of the mesh
     * @returns The class name
     */
    getClassName(): string;
}
/**
 * Represents a physics imposter
 * @see https://doc.babylonjs.com/features/featuresDeepDive/physics/usingPhysicsEngine
 */
export declare class PhysicsImpostor {
    /**
     * The physics-enabled object used as the physics imposter
     */
    object: IPhysicsEnabledObject;
    /**
     * The type of the physics imposter
     */
    type: number;
    private _options;
    private _scene?;
    /**
     * The default object size of the imposter
     */
    static DEFAULT_OBJECT_SIZE: Vector3;
    /**
     * The identity quaternion of the imposter
     */
    static IDENTITY_QUATERNION: Quaternion;
    /** @internal */
    _pluginData: any;
    private _physicsEngine;
    private _physicsBody;
    private _bodyUpdateRequired;
    private _onBeforePhysicsStepCallbacks;
    private _onAfterPhysicsStepCallbacks;
    /** @internal */
    _onPhysicsCollideCallbacks: Array<{
        callback: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor, point: Nullable<Vector3>, distance: number, impulse: number, normal: Nullable<Vector3>) => void;
        otherImpostors: Array<PhysicsImpostor>;
    }>;
    private _deltaPosition;
    private _deltaRotation;
    private _deltaRotationConjugated;
    /** @internal */
    _isFromLine: boolean;
    private _parent;
    private _isDisposed;
    private static _TmpVecs;
    private static _TmpQuat;
    /**
     * Specifies if the physics imposter is disposed
     */
    get isDisposed(): boolean;
    /**
     * Gets the mass of the physics imposter
     */
    get mass(): number;
    set mass(value: number);
    /**
     * Gets the coefficient of friction
     */
    get friction(): number;
    /**
     * Sets the coefficient of friction
     */
    set friction(value: number);
    /**
     * Gets the coefficient of restitution
     */
    get restitution(): number;
    /**
     * Sets the coefficient of restitution
     */
    set restitution(value: number);
    /**
     * Gets the pressure of a soft body; only supported by the AmmoJSPlugin
     */
    get pressure(): number;
    /**
     * Sets the pressure of a soft body; only supported by the AmmoJSPlugin
     */
    set pressure(value: number);
    /**
     * Gets the stiffness of a soft body; only supported by the AmmoJSPlugin
     */
    get stiffness(): number;
    /**
     * Sets the stiffness of a soft body; only supported by the AmmoJSPlugin
     */
    set stiffness(value: number);
    /**
     * Gets the velocityIterations of a soft body; only supported by the AmmoJSPlugin
     */
    get velocityIterations(): number;
    /**
     * Sets the velocityIterations of a soft body; only supported by the AmmoJSPlugin
     */
    set velocityIterations(value: number);
    /**
     * Gets the positionIterations of a soft body; only supported by the AmmoJSPlugin
     */
    get positionIterations(): number;
    /**
     * Sets the positionIterations of a soft body; only supported by the AmmoJSPlugin
     */
    set positionIterations(value: number);
    /**
     * The unique id of the physics imposter
     * set by the physics engine when adding this impostor to the array
     */
    uniqueId: number;
    /**
     * @internal
     */
    soft: boolean;
    /**
     * @internal
     */
    segments: number;
    private _joints;
    /**
     * Initializes the physics imposter
     * @param object The physics-enabled object used as the physics imposter
     * @param type The type of the physics imposter. Types are available as static members of this class.
     * @param _options The options for the physics imposter
     * @param _scene The Babylon scene
     */
    constructor(
    /**
     * The physics-enabled object used as the physics imposter
     */
    object: IPhysicsEnabledObject, 
    /**
     * The type of the physics imposter
     */
    type: number, _options?: PhysicsImpostorParameters, _scene?: Scene | undefined);
    /**
     * This function will completely initialize this impostor.
     * It will create a new body - but only if this mesh has no parent.
     * If it has, this impostor will not be used other than to define the impostor
     * of the child mesh.
     * @internal
     */
    _init(): void;
    private _getPhysicsParent;
    /**
     * Should a new body be generated.
     * @returns boolean specifying if body initialization is required
     */
    isBodyInitRequired(): boolean;
    /**
     * Sets the updated scaling
     */
    setScalingUpdated(): void;
    /**
     * Force a regeneration of this or the parent's impostor's body.
     * Use with caution - This will remove all previously-instantiated joints.
     */
    forceUpdate(): void;
    /**
     * Gets the body that holds this impostor. Either its own, or its parent.
     */
    get physicsBody(): any;
    /**
     * Get the parent of the physics imposter
     * @returns Physics imposter or null
     */
    get parent(): Nullable<PhysicsImpostor>;
    /**
     * Sets the parent of the physics imposter
     */
    set parent(value: Nullable<PhysicsImpostor>);
    /**
     * Set the physics body. Used mainly by the physics engine/plugin
     */
    set physicsBody(physicsBody: any);
    /**
     * Resets the update flags
     */
    resetUpdateFlags(): void;
    /**
     * Gets the object extents
     * @returns the object extents
     */
    getObjectExtents(): Vector3;
    /**
     * Gets the object center
     * @returns The object center
     */
    getObjectCenter(): Vector3;
    /**
     * Get a specific parameter from the options parameters
     * @param paramName The object parameter name
     * @returns The object parameter
     */
    getParam(paramName: string): any;
    /**
     * Sets a specific parameter in the options given to the physics plugin
     * @param paramName The parameter name
     * @param value The value of the parameter
     */
    setParam(paramName: string, value: number): void;
    /**
     * Specifically change the body's mass. Won't recreate the physics body object
     * @param mass The mass of the physics imposter
     */
    setMass(mass: number): void;
    /**
     * Gets the linear velocity
     * @returns  linear velocity or null
     */
    getLinearVelocity(): Nullable<Vector3>;
    /**
     * Sets the linear velocity
     * @param velocity  linear velocity or null
     */
    setLinearVelocity(velocity: Nullable<Vector3>): void;
    /**
     * Gets the angular velocity
     * @returns angular velocity or null
     */
    getAngularVelocity(): Nullable<Vector3>;
    /**
     * Sets the angular velocity
     * @param velocity The velocity or null
     */
    setAngularVelocity(velocity: Nullable<Vector3>): void;
    /**
     * Execute a function with the physics plugin native code
     * Provide a function the will have two variables - the world object and the physics body object
     * @param func The function to execute with the physics plugin native code
     */
    executeNativeFunction(func: (world: any, physicsBody: any) => void): void;
    /**
     * Register a function that will be executed before the physics world is stepping forward
     * @param func The function to execute before the physics world is stepped forward
     */
    registerBeforePhysicsStep(func: (impostor: PhysicsImpostor) => void): void;
    /**
     * Unregister a function that will be executed before the physics world is stepping forward
     * @param func The function to execute before the physics world is stepped forward
     */
    unregisterBeforePhysicsStep(func: (impostor: PhysicsImpostor) => void): void;
    /**
     * Register a function that will be executed after the physics step
     * @param func The function to execute after physics step
     */
    registerAfterPhysicsStep(func: (impostor: PhysicsImpostor) => void): void;
    /**
     * Unregisters a function that will be executed after the physics step
     * @param func The function to execute after physics step
     */
    unregisterAfterPhysicsStep(func: (impostor: PhysicsImpostor) => void): void;
    /**
     * register a function that will be executed when this impostor collides against a different body
     * @param collideAgainst Physics imposter, or array of physics imposters to collide against
     * @param func Callback that is executed on collision
     */
    registerOnPhysicsCollide(collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>, func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor, point: Nullable<Vector3>) => void): void;
    /**
     * Unregisters the physics imposter's collision callback
     * @param collideAgainst The physics object to collide against
     * @param func Callback to execute on collision
     */
    unregisterOnPhysicsCollide(collideAgainst: PhysicsImpostor | Array<PhysicsImpostor>, func: (collider: PhysicsImpostor, collidedAgainst: PhysicsImpostor | Array<PhysicsImpostor>, point: Nullable<Vector3>) => void): void;
    private _tmpQuat;
    private _tmpQuat2;
    /**
     * Get the parent rotation
     * @returns The parent rotation
     */
    getParentsRotation(): Quaternion;
    /**
     * this function is executed by the physics engine.
     */
    beforeStep: () => void;
    /**
     * this function is executed by the physics engine
     */
    afterStep: () => void;
    /**
     * Legacy collision detection event support
     */
    onCollideEvent: Nullable<(collider: PhysicsImpostor, collidedWith: PhysicsImpostor) => void>;
    /**
     *  define an onCollide function to call when this impostor collides against a different body
     * @param e collide event data
     */
    onCollide: (e: {
        body: any;
        point: Nullable<Vector3>;
        distance: number;
        impulse: number;
        normal: Nullable<Vector3>;
    }) => void;
    /**
     * Apply a force
     * @param force The force to apply
     * @param contactPoint The contact point for the force
     * @returns The physics imposter
     */
    applyForce(force: Vector3, contactPoint: Vector3): PhysicsImpostor;
    /**
     * Apply an impulse
     * @param force The impulse force
     * @param contactPoint The contact point for the impulse force
     * @returns The physics imposter
     */
    applyImpulse(force: Vector3, contactPoint: Vector3): PhysicsImpostor;
    /**
     * A help function to create a joint
     * @param otherImpostor A physics imposter used to create a joint
     * @param jointType The type of joint
     * @param jointData The data for the joint
     * @returns The physics imposter
     */
    createJoint(otherImpostor: PhysicsImpostor, jointType: number, jointData: PhysicsJointData): PhysicsImpostor;
    /**
     * Add a joint to this impostor with a different impostor
     * @param otherImpostor A physics imposter used to add a joint
     * @param joint The joint to add
     * @returns The physics imposter
     */
    addJoint(otherImpostor: PhysicsImpostor, joint: PhysicsJoint): PhysicsImpostor;
    /**
     * Add an anchor to a cloth impostor
     * @param otherImpostor rigid impostor to anchor to
     * @param width ratio across width from 0 to 1
     * @param height ratio up height from 0 to 1
     * @param influence the elasticity between cloth impostor and anchor from 0, very stretchy to 1, little stretch
     * @param noCollisionBetweenLinkedBodies when true collisions between cloth impostor and anchor are ignored; default false
     * @returns impostor the soft imposter
     */
    addAnchor(otherImpostor: PhysicsImpostor, width: number, height: number, influence: number, noCollisionBetweenLinkedBodies: boolean): PhysicsImpostor;
    /**
     * Add a hook to a rope impostor
     * @param otherImpostor rigid impostor to anchor to
     * @param length ratio across rope from 0 to 1
     * @param influence the elasticity between rope impostor and anchor from 0, very stretchy to 1, little stretch
     * @param noCollisionBetweenLinkedBodies when true collisions between soft impostor and anchor are ignored; default false
     * @returns impostor the rope imposter
     */
    addHook(otherImpostor: PhysicsImpostor, length: number, influence: number, noCollisionBetweenLinkedBodies: boolean): PhysicsImpostor;
    /**
     * Will keep this body still, in a sleep mode.
     * @returns the physics imposter
     */
    sleep(): PhysicsImpostor;
    /**
     * Wake the body up.
     * @returns The physics imposter
     */
    wakeUp(): PhysicsImpostor;
    /**
     * Clones the physics imposter
     * @param newObject The physics imposter clones to this physics-enabled object
     * @returns A nullable physics imposter
     */
    clone(newObject: IPhysicsEnabledObject): Nullable<PhysicsImpostor>;
    /**
     * Disposes the physics imposter
     */
    dispose(): void;
    /**
     * Sets the delta position
     * @param position The delta position amount
     */
    setDeltaPosition(position: Vector3): void;
    /**
     * Sets the delta rotation
     * @param rotation The delta rotation amount
     */
    setDeltaRotation(rotation: Quaternion): void;
    /**
     * Gets the box size of the physics imposter and stores the result in the input parameter
     * @param result Stores the box size
     * @returns The physics imposter
     */
    getBoxSizeToRef(result: Vector3): PhysicsImpostor;
    /**
     * Gets the radius of the physics imposter
     * @returns Radius of the physics imposter
     */
    getRadius(): number;
    /**
     * Sync a bone with this impostor
     * @param bone The bone to sync to the impostor.
     * @param boneMesh The mesh that the bone is influencing.
     * @param jointPivot The pivot of the joint / bone in local space.
     * @param distToJoint Optional distance from the impostor to the joint.
     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.
     */
    syncBoneWithImpostor(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion): void;
    /**
     * Sync impostor to a bone
     * @param bone The bone that the impostor will be synced to.
     * @param boneMesh The mesh that the bone is influencing.
     * @param jointPivot The pivot of the joint / bone in local space.
     * @param distToJoint Optional distance from the impostor to the joint.
     * @param adjustRotation Optional quaternion for adjusting the local rotation of the bone.
     * @param boneAxis Optional vector3 axis the bone is aligned with
     */
    syncImpostorWithBone(bone: Bone, boneMesh: AbstractMesh, jointPivot: Vector3, distToJoint?: number, adjustRotation?: Quaternion, boneAxis?: Vector3): void;
    /**
     * No-Imposter type
     */
    static NoImpostor: number;
    /**
     * Sphere-Imposter type
     */
    static SphereImpostor: number;
    /**
     * Box-Imposter type
     */
    static BoxImpostor: number;
    /**
     * Plane-Imposter type
     */
    static PlaneImpostor: number;
    /**
     * Mesh-imposter type (Only available to objects with vertices data)
     */
    static MeshImpostor: number;
    /**
     * Capsule-Impostor type (Ammo.js plugin only)
     */
    static CapsuleImpostor: number;
    /**
     * Cylinder-Imposter type
     */
    static CylinderImpostor: number;
    /**
     * Particle-Imposter type
     */
    static ParticleImpostor: number;
    /**
     * Heightmap-Imposter type
     */
    static HeightmapImpostor: number;
    /**
     * ConvexHull-Impostor type (Ammo.js plugin only)
     */
    static ConvexHullImpostor: number;
    /**
     * Custom-Imposter type (Ammo.js plugin only)
     */
    static CustomImpostor: number;
    /**
     * Rope-Imposter type
     */
    static RopeImpostor: number;
    /**
     * Cloth-Imposter type
     */
    static ClothImpostor: number;
    /**
     * Softbody-Imposter type
     */
    static SoftbodyImpostor: number;
}
