/**
 * The RigidBodyComponent, when combined with a {@link CollisionComponent}, allows your entities
 * to be simulated using realistic physics. A RigidBodyComponent will fall under gravity and
 * collide with other rigid bodies. Using scripts, you can apply forces and impulses to rigid
 * bodies.
 *
 * You should never need to use the RigidBodyComponent constructor directly. To add an
 * RigidBodyComponent to an {@link Entity}, use {@link Entity#addComponent}:
 *
 * ```javascript
 * // Create a static 1x1x1 box-shaped rigid body
 * const entity = pc.Entity();
 * entity.addComponent('collision'); // Without options, this defaults to a 1x1x1 box shape
 * entity.addComponent('rigidbody'); // Without options, this defaults to a 'static' body
 * ```
 *
 * To create a dynamic sphere with mass of 10, do:
 *
 * ```javascript
 * const entity = pc.Entity();
 * entity.addComponent('collision', {
 *     type: 'sphere'
 * });
 * entity.addComponent('rigidbody', {
 *     type: 'dynamic',
 *     mass: 10
 * });
 * ```
 *
 * Once the RigidBodyComponent is added to the entity, you can access it via the
 * {@link Entity#rigidbody} property:
 *
 * ```javascript
 * entity.rigidbody.mass = 10;
 * console.log(entity.rigidbody.mass);
 * ```
 *
 * Relevant Engine API examples:
 *
 * - [Falling shapes](https://playcanvas.github.io/#/physics/falling-shapes)
 * - [Vehicle physics](https://playcanvas.github.io/#/physics/vehicle)
 *
 * @hideconstructor
 * @category Physics
 */
export class RigidBodyComponent extends Component {
    /**
     * Fired when a contact occurs between two rigid bodies. The handler is passed a
     * {@link ContactResult} object containing details of the contact between the two rigid bodies.
     *
     * @event
     * @example
     * entity.rigidbody.on('contact', (result) => {
     *    console.log(`Contact between ${entity.name} and ${result.other.name}`);
     * });
     */
    static EVENT_CONTACT: string;
    /**
     * Fired when two rigid bodies start touching. The handler is passed a {@link ContactResult}
     * object containing details of the contact between the two rigid bodies.
     *
     * @event
     * @example
     * entity.rigidbody.on('collisionstart', (result) => {
     *     console.log(`Collision started between ${entity.name} and ${result.other.name}`);
     * });
     */
    static EVENT_COLLISIONSTART: string;
    /**
     * Fired when two rigid bodies stop touching. The handler is passed an {@link Entity} that
     * represents the other rigid body involved in the collision.
     *
     * @event
     * @example
     * entity.rigidbody.on('collisionend', (other) => {
     *     console.log(`${entity.name} stopped touching ${other.name}`);
     * });
     */
    static EVENT_COLLISIONEND: string;
    /**
     * Fired when a rigid body enters a trigger volume. The handler is passed an {@link Entity}
     * representing the trigger volume that this rigid body entered.
     *
     * @event
     * @example
     * entity.rigidbody.on('triggerenter', (trigger) => {
     *     console.log(`Entity ${entity.name} entered trigger volume ${trigger.name}`);
     * });
     */
    static EVENT_TRIGGERENTER: string;
    /**
     * Fired when a rigid body exits a trigger volume. The handler is passed an {@link Entity}
     * representing the trigger volume that this rigid body exited.
     *
     * @event
     * @example
     * entity.rigidbody.on('triggerleave', (trigger) => {
     *     console.log(`Entity ${entity.name} exited trigger volume ${trigger.name}`);
     * });
     */
    static EVENT_TRIGGERLEAVE: string;
    /** @ignore */
    static onLibraryLoaded(): void;
    /** @ignore */
    static onAppDestroy(): void;
    /** @private */
    private _angularDamping;
    /** @private */
    private _angularFactor;
    /** @private */
    private _angularVelocity;
    /** @private */
    private _body;
    /** @private */
    private _friction;
    /** @private */
    private _group;
    /** @private */
    private _linearDamping;
    /** @private */
    private _linearFactor;
    /** @private */
    private _linearVelocity;
    /** @private */
    private _mask;
    /** @private */
    private _mass;
    /** @private */
    private _restitution;
    /** @private */
    private _rollingFriction;
    /** @private */
    private _simulationEnabled;
    /** @private */
    private _type;
    /**
     * Sets the rate at which a body loses angular velocity over time.
     *
     * @type {number}
     */
    set angularDamping(damping: number);
    /**
     * Gets the rate at which a body loses angular velocity over time.
     *
     * @type {number}
     */
    get angularDamping(): number;
    /**
     * Sets the scaling factor for angular movement of the body in each axis. Only valid for rigid
     * bodies of type {@link BODYTYPE_DYNAMIC}. Defaults to 1 in all axes (body can freely rotate).
     *
     * @type {Vec3}
     */
    set angularFactor(factor: Vec3);
    /**
     * Gets the scaling factor for angular movement of the body in each axis.
     *
     * @type {Vec3}
     */
    get angularFactor(): Vec3;
    /**
     * Sets the rotational speed of the body around each world axis.
     *
     * @type {Vec3}
     */
    set angularVelocity(velocity: Vec3);
    /**
     * Gets the rotational speed of the body around each world axis.
     *
     * @type {Vec3}
     */
    get angularVelocity(): Vec3;
    set body(body: any);
    get body(): any;
    /**
     * Sets the friction value used when contacts occur between two bodies. A higher value indicates
     * more friction. Should be set in the range 0 to 1. Defaults to 0.5.
     *
     * @type {number}
     */
    set friction(friction: number);
    /**
     * Gets the friction value used when contacts occur between two bodies.
     *
     * @type {number}
     */
    get friction(): number;
    /**
     * Sets the collision group this body belongs to. Combine the group and the mask to prevent bodies
     * colliding with each other. Defaults to 1.
     *
     * @type {number}
     */
    set group(group: number);
    /**
     * Gets the collision group this body belongs to.
     *
     * @type {number}
     */
    get group(): number;
    /**
     * Sets the rate at which a body loses linear velocity over time. Defaults to 0.
     *
     * @type {number}
     */
    set linearDamping(damping: number);
    /**
     * Gets the rate at which a body loses linear velocity over time.
     *
     * @type {number}
     */
    get linearDamping(): number;
    /**
     * Sets the scaling factor for linear movement of the body in each axis. Only valid for rigid
     * bodies of type {@link BODYTYPE_DYNAMIC}. Defaults to 1 in all axes (body can freely move).
     *
     * @type {Vec3}
     */
    set linearFactor(factor: Vec3);
    /**
     * Gets the scaling factor for linear movement of the body in each axis.
     *
     * @type {Vec3}
     */
    get linearFactor(): Vec3;
    /**
     * Sets the speed of the body in a given direction.
     *
     * @type {Vec3}
     */
    set linearVelocity(velocity: Vec3);
    /**
     * Gets the speed of the body in a given direction.
     *
     * @type {Vec3}
     */
    get linearVelocity(): Vec3;
    /**
     * Sets the collision mask sets which groups this body collides with. It is a bit field of 16
     * bits, the first 8 bits are reserved for engine use. Defaults to 65535.
     *
     * @type {number}
     */
    set mask(mask: number);
    /**
     * Gets the collision mask sets which groups this body collides with.
     *
     * @type {number}
     */
    get mask(): number;
    /**
     * Sets the mass of the body. This is only relevant for {@link BODYTYPE_DYNAMIC} bodies, other
     * types have infinite mass. Defaults to 1.
     *
     * @type {number}
     */
    set mass(mass: number);
    /**
     * Gets the mass of the body.
     *
     * @type {number}
     */
    get mass(): number;
    /**
     * Sets the value that controls the amount of energy lost when two rigid bodies collide. The
     * calculation multiplies the restitution values for both colliding bodies. A multiplied value
     * of 0 means that all energy is lost in the collision while a value of 1 means that no energy
     * is lost. Should be set in the range 0 to 1. Defaults to 0.
     *
     * @type {number}
     */
    set restitution(restitution: number);
    /**
     * Gets the value that controls the amount of energy lost when two rigid bodies collide.
     *
     * @type {number}
     */
    get restitution(): number;
    /**
     * Sets the torsional friction orthogonal to the contact point. Defaults to 0.
     *
     * @type {number}
     */
    set rollingFriction(friction: number);
    /**
     * Gets the torsional friction orthogonal to the contact point.
     *
     * @type {number}
     */
    get rollingFriction(): number;
    /**
     * Sets the rigid body type determines how the body is simulated. Can be:
     *
     * - {@link BODYTYPE_STATIC}: infinite mass and cannot move.
     * - {@link BODYTYPE_DYNAMIC}: simulated according to applied forces.
     * - {@link BODYTYPE_KINEMATIC}: infinite mass and does not respond to forces (can only be
     * moved by setting the position and rotation of component's {@link Entity}).
     *
     * Defaults to {@link BODYTYPE_STATIC}.
     *
     * @type {string}
     */
    set type(type: string);
    /**
     * Gets the rigid body type determines how the body is simulated.
     *
     * @type {string}
     */
    get type(): string;
    /**
     * If the Entity has a Collision shape attached then create a rigid body using this shape. This
     * method destroys the existing body.
     *
     * @private
     */
    private createBody;
    /**
     * Returns true if the rigid body is currently actively being simulated. I.e. Not 'sleeping'.
     *
     * @returns {boolean} True if the body is active.
     */
    isActive(): boolean;
    /**
     * Forcibly activate the rigid body simulation. Only affects rigid bodies of type
     * {@link BODYTYPE_DYNAMIC}.
     */
    activate(): void;
    /**
     * Add a body to the simulation.
     *
     * @ignore
     */
    enableSimulation(): void;
    /**
     * Remove a body from the simulation.
     *
     * @ignore
     */
    disableSimulation(): void;
    /**
     * Apply a force to the body at a point. By default, the force is applied at the origin of the
     * body. However, the force can be applied at an offset this point by specifying a world space
     * vector from the body's origin to the point of application.
     *
     * @overload
     * @param {number} x - X-component of the force in world space.
     * @param {number} y - Y-component of the force in world space.
     * @param {number} z - Z-component of the force in world space.
     * @param {number} [px] - X-component of the relative point at which to apply the force in
     * world space.
     * @param {number} [py] - Y-component of the relative point at which to apply the force in
     * world space.
     * @param {number} [pz] - Z-component of the relative point at which to apply the force in
     * world space.
     * @returns {void}
     * @example
     * // Apply an approximation of gravity at the body's center
     * this.entity.rigidbody.applyForce(0, -10, 0);
     * @example
     * // Apply an approximation of gravity at 1 unit down the world Z from the center of the body
     * this.entity.rigidbody.applyForce(0, -10, 0, 0, 0, 1);
     */
    applyForce(x: number, y: number, z: number, px?: number, py?: number, pz?: number): void;
    /**
     * Apply a force to the body at a point. By default, the force is applied at the origin of the
     * body. However, the force can be applied at an offset this point by specifying a world space
     * vector from the body's origin to the point of application.
     *
     * @overload
     * @param {Vec3} force - Vector representing the force in world space.
     * @param {Vec3} [relativePoint] - Optional vector representing the relative point at which to
     * apply the force in world space.
     * @returns {void}
     * @example
     * // Calculate a force vector pointing in the world space direction of the entity
     * const force = this.entity.forward.clone().mulScalar(100);
     *
     * // Apply the force at the body's center
     * this.entity.rigidbody.applyForce(force);
     * @example
     * // Apply a force at some relative offset from the body's center
     * // Calculate a force vector pointing in the world space direction of the entity
     * const force = this.entity.forward.clone().mulScalar(100);
     *
     * // Calculate the world space relative offset
     * const relativePoint = new pc.Vec3();
     * const childEntity = this.entity.findByName('Engine');
     * relativePoint.sub2(childEntity.getPosition(), this.entity.getPosition());
     *
     * // Apply the force
     * this.entity.rigidbody.applyForce(force, relativePoint);
     */
    applyForce(force: Vec3, relativePoint?: Vec3): void;
    /**
     * Apply torque (rotational force) to the body.
     *
     * @overload
     * @param {number} x - The x-component of the torque force in world space.
     * @param {number} y - The y-component of the torque force in world space.
     * @param {number} z - The z-component of the torque force in world space.
     * @returns {void}
     * @example
     * entity.rigidbody.applyTorque(0, 10, 0);
     */
    applyTorque(x: number, y: number, z: number): void;
    /**
     * Apply torque (rotational force) to the body.
     *
     * @overload
     * @param {Vec3} torque - Vector representing the torque force in world space.
     * @returns {void}
     * @example
     * const torque = new pc.Vec3(0, 10, 0);
     * entity.rigidbody.applyTorque(torque);
     */
    applyTorque(torque: Vec3): void;
    /**
     * Apply an impulse (instantaneous change of velocity) to the body at a point.
     *
     * @overload
     * @param {number} x - X-component of the impulse in world space.
     * @param {number} y - Y-component of the impulse in world space.
     * @param {number} z - Z-component of the impulse in world space.
     * @param {number} [px] - X-component of the point at which to apply the impulse in the local
     * space of the entity.
     * @param {number} [py] - Y-component of the point at which to apply the impulse in the local
     * space of the entity.
     * @param {number} [pz] - Z-component of the point at which to apply the impulse in the local
     * space of the entity.
     * @returns {void}
     * @example
     * // Apply an impulse along the world space positive y-axis at the entity's position.
     * entity.rigidbody.applyImpulse(0, 10, 0);
     * @example
     * // Apply an impulse along the world space positive y-axis at 1 unit down the positive
     * // z-axis of the entity's local space.
     * entity.rigidbody.applyImpulse(0, 10, 0, 0, 0, 1);
     */
    applyImpulse(x: number, y: number, z: number, px?: number, py?: number, pz?: number): void;
    /**
     * Apply an impulse (instantaneous change of velocity) to the body at a point.
     *
     * @overload
     * @param {Vec3} impulse - Vector representing the impulse in world space.
     * @param {Vec3} [relativePoint] - Optional vector representing the relative point at which to
     * apply the impulse in the local space of the entity.
     * @returns {void}
     * @example
     * // Apply an impulse along the world space positive y-axis at the entity's position.
     * const impulse = new pc.Vec3(0, 10, 0);
     * entity.rigidbody.applyImpulse(impulse);
     * @example
     * // Apply an impulse along the world space positive y-axis at 1 unit down the positive
     * // z-axis of the entity's local space.
     * const impulse = new pc.Vec3(0, 10, 0);
     * const relativePoint = new pc.Vec3(0, 0, 1);
     * entity.rigidbody.applyImpulse(impulse, relativePoint);
     */
    applyImpulse(impulse: Vec3, relativePoint?: Vec3): void;
    /**
     * Apply a torque impulse (rotational force applied instantaneously) to the body.
     *
     * @overload
     * @param {number} x - X-component of the torque impulse in world space.
     * @param {number} y - Y-component of the torque impulse in world space.
     * @param {number} z - Z-component of the torque impulse in world space.
     * @returns {void}
     * @example
     * entity.rigidbody.applyTorqueImpulse(0, 10, 0);
     */
    applyTorqueImpulse(x: number, y: number, z: number): void;
    /**
     * Apply a torque impulse (rotational force applied instantaneously) to the body.
     *
     * @overload
     * @param {Vec3} torque - Vector representing the torque impulse in world space.
     * @returns {void}
     * @example
     * const torque = new pc.Vec3(0, 10, 0);
     * entity.rigidbody.applyTorqueImpulse(torque);
     */
    applyTorqueImpulse(torque: Vec3): void;
    /**
     * Returns true if the rigid body is of type {@link BODYTYPE_STATIC}.
     *
     * @returns {boolean} True if static.
     */
    isStatic(): boolean;
    /**
     * Returns true if the rigid body is of type {@link BODYTYPE_STATIC} or {@link BODYTYPE_KINEMATIC}.
     *
     * @returns {boolean} True if static or kinematic.
     */
    isStaticOrKinematic(): boolean;
    /**
     * Returns true if the rigid body is of type {@link BODYTYPE_KINEMATIC}.
     *
     * @returns {boolean} True if kinematic.
     */
    isKinematic(): boolean;
    /**
     * Writes an entity transform into an Ammo.btTransform but ignoring scale.
     *
     * @param {object} transform - The ammo transform to write the entity transform to.
     * @private
     */
    private _getEntityTransform;
    /**
     * Set the rigid body transform to be the same as the Entity transform. This must be called
     * after any Entity transformation functions (e.g. {@link Entity#setPosition}) are called in
     * order to update the rigid body to match the Entity.
     *
     * @private
     */
    private syncEntityToBody;
    /**
     * Sets an entity's transform to match that of the world transformation matrix of a dynamic
     * rigid body's motion state.
     *
     * @private
     */
    private _updateDynamic;
    /**
     * Writes the entity's world transformation matrix into the motion state of a kinematic body.
     *
     * @private
     */
    private _updateKinematic;
    /**
     * Teleport an entity to a new world space position, optionally setting orientation. This
     * function should only be called for rigid bodies that are dynamic.
     *
     * @overload
     * @param {number} x - X-coordinate of the new world space position.
     * @param {number} y - Y-coordinate of the new world space position.
     * @param {number} z - Z-coordinate of the new world space position.
     * @param {number} [rx] - X-rotation of the world space Euler angles in degrees.
     * @param {number} [ry] - Y-rotation of the world space Euler angles in degrees.
     * @param {number} [rz] - Z-rotation of the world space Euler angles in degrees.
     * @returns {void}
     * @example
     * // Teleport the entity to the origin
     * entity.rigidbody.teleport(0, 0, 0);
     * @example
     * // Teleport the entity to world space coordinate [1, 2, 3] and reset orientation
     * entity.rigidbody.teleport(1, 2, 3, 0, 0, 0);
     */
    teleport(x: number, y: number, z: number, rx?: number, ry?: number, rz?: number): void;
    /**
     * Teleport an entity to a new world space position, optionally setting orientation. This
     * function should only be called for rigid bodies that are dynamic.
     *
     * @overload
     * @param {Vec3} position - Vector holding the new world space position.
     * @param {Vec3} [angles] - Vector holding the new world space Euler angles in degrees.
     * @returns {void}
     * @example
     * // Teleport the entity to the origin
     * entity.rigidbody.teleport(pc.Vec3.ZERO);
     * @example
     * // Teleport the entity to world space coordinate [1, 2, 3] and reset orientation
     * const position = new pc.Vec3(1, 2, 3);
     * entity.rigidbody.teleport(position, pc.Vec3.ZERO);
     */
    teleport(position: Vec3, angles?: Vec3): void;
    /**
     * Teleport an entity to a new world space position, optionally setting orientation. This
     * function should only be called for rigid bodies that are dynamic.
     *
     * @overload
     * @param {Vec3} position - Vector holding the new world space position.
     * @param {Quat} [rotation] - Quaternion holding the new world space rotation.
     * @returns {void}
     * @example
     * // Teleport the entity to the origin
     * entity.rigidbody.teleport(pc.Vec3.ZERO);
     * @example
     * // Teleport the entity to world space coordinate [1, 2, 3] and reset orientation
     * const position = new pc.Vec3(1, 2, 3);
     * entity.rigidbody.teleport(position, pc.Quat.IDENTITY);
     */
    teleport(position: Vec3, rotation?: Quat): void;
}
import { Component } from '../component.js';
import { Vec3 } from '../../../core/math/vec3.js';
import { Quat } from '../../../core/math/quat.js';
