import { vec2 } from "gl-matrix";
import { System } from "../system";
import CollisionObject from "./collisionObject";
import RigidBody from "./rigidbody";
import CollisionsSpace from "./spaces/collisions";
import DynamicsSpace from "./spaces/dynamics";
import Ray from "./ray";
import ConstraintSpace from "./spaces/constraints";
import Constraint from "./constraints/constraint";
import Fluid from "./fluid/fluid";
import TimeStep from "../timestep";
export interface PhysicsConfig {
    POINT_SIZE: number;
    CACHED_CONTACTS_TOLERANCE: number;
    RESTITUTION_THRESHOLD: number;
    VELOCITY_ITERATIONS: number;
    ACUMMULATE_IMPULSE: boolean;
    WARM_IMPULSE: boolean;
    POSITION_ITERATIONS: number;
    POSITION_SLOP: number;
    POSITION_DAMPING: number;
    POSITION_WARMING: number;
    POSITION_SCALE: number;
    EPA_TOLERANCE: number;
    EPA_MAX_ITERATIONS: number;
    CONSTRAINT_ITERATIONS: number;
}
/**
 * Handles physics for bodies added to the engine.
 *
 * Raycasting can only check against objects in the phsyics engine's collisions space.
 *
 * At the start of each `update` call the static `G_CONF` variable is set to the instances `CONFIG` variable.
 * This allows for easy access to the physics config from other parts of the physics system.
 */
export default class Physics implements System {
    static G_CONF: {
        POINT_SIZE: number;
        CACHED_CONTACTS_TOLERANCE: number;
        RESTITUTION_THRESHOLD: number;
        VELOCITY_ITERATIONS: number;
        ACUMMULATE_IMPULSE: boolean;
        WARM_IMPULSE: boolean;
        POSITION_ITERATIONS: number;
        POSITION_SLOP: number;
        POSITION_DAMPING: number;
        POSITION_WARMING: number;
        POSITION_SCALE: number;
        EPA_TOLERANCE: number;
        EPA_MAX_ITERATIONS: number;
        CONSTRAINT_ITERATIONS: number;
    };
    CONFIG: {
        POINT_SIZE: number;
        CACHED_CONTACTS_TOLERANCE: number;
        RESTITUTION_THRESHOLD: number;
        VELOCITY_ITERATIONS: number;
        ACUMMULATE_IMPULSE: boolean;
        WARM_IMPULSE: boolean;
        POSITION_ITERATIONS: number;
        POSITION_SLOP: number;
        POSITION_DAMPING: number;
        POSITION_WARMING: number;
        POSITION_SCALE: number;
        EPA_TOLERANCE: number;
        EPA_MAX_ITERATIONS: number;
        CONSTRAINT_ITERATIONS: number;
    };
    private gravity;
    dynamicsSpace: DynamicsSpace;
    collisionsSpace: CollisionsSpace;
    constraintSpace: ConstraintSpace;
    fluids: Fluid[];
    /**
     * The amount of time in ms that the last physics step took.
     */
    physicsTime: number;
    /**
     * The time in ms that the last broadphase collision detection step took.
     */
    broadphaseTime: number;
    /**
     * The time in ms that the last narrowphase collision detection step took.
     */
    narrowphaseTime: number;
    /**
     * The time in ms that the last collision solving steps took.
     */
    collisionSolveTime: number;
    /**
     * The time in ms that the last constraint solving steps took.
     */
    constraintTime: number;
    /**
     * The time in ms that the last dynamics solving steps took.
     */
    dynamicsTime: number;
    /**
     * The time in ms that the last fluid solving steps took.
     */
    fluidTime: number;
    /**
     * Enable/disable debug tools.
     */
    debug: boolean;
    /**
     * Create an {@link Physics} instance.
     *
     * @param gravity The gravitional force applied to objects in the system
     */
    constructor(gravity?: vec2);
    /**
     * Steps the physics world forward by the given delta time.
     *
     * Order of updates is very important.
     *
     * @param ts The {@link TimeStep} for this update.
     */
    update(ts: TimeStep): void;
    drawDebug(): void;
    /**
     * Point pick objects.
     *
     * **NOTE: Picking only checks objects in the {@link CollisionsSpace}.**
     *
     * @param point The point to pick objects at
     */
    pick(point: vec2): CollisionObject[];
    /**
     * raycast objects.
     *
     * **NOTE: Raycast only checks objects in the {@link CollisionsSpace}.**
     *
     * @param ray The ray to cast
     */
    raycast(ray: Ray): CollisionObject[];
    /**
     * Adds a {@link CollisionObject} to the world's collisions space.
     *
     * @param c The collision object to add
     */
    addCollisionObj(c: CollisionObject): void;
    /**
     * Adds a {@link RigidBody} to the world's dynamics space.
     *
     * @param obj The object to add
     */
    addDynamicsObj(obj: RigidBody): void;
    /**
     * Adds a {@link Rigidbody} to the world's dynamics and collisions spaces.
     *
     * @param body The body to add
     */
    addBody(body: RigidBody): void;
    /**
     * Adds the given bodies to the world's dynamics and collisions spaces.
     *
     * @param bodies The bodies to add
     */
    addBodies(...bodies: RigidBody[]): void;
    /**
     * Removes a {@link CollisionObject} from the world's collisions space.
     *
     * @param c The collision object to remove
     */
    removeCollisionObj(c: CollisionObject): void;
    /**
     * Removes a {@link RigidBody} from the world's dynamics space.
     *
     * @param obj The object to remove
     */
    removeDynamicsObj(obj: RigidBody): void;
    /**
     * Removes a {@link Rigidbody} from the world's dynamics and collisions spaces.
     *
     * @param body The body to remove
     */
    removeBody(body: RigidBody): void;
    /**
     * Removes the given bodies from the world's dynamics and collision spaces.
     *
     * @param bodies The bodies to remove
     */
    removeBodies(...bodies: RigidBody[]): void;
    /**
     * Adds a {@link Constraint} to the world's constraint space.
     *
     * @param constraint The constraint to add
     */
    addConstraint(constraint: Constraint): void;
    /**
     * Removes a {@link Constraint} from the world's constraint space.
     *
     * @param constraint The constraint to remove
     */
    removeConstraint(constraint: Constraint): void;
    /**
     * Adds the given fluid to the physics world.
     *
     * @param fluid The fluid to add
     */
    addFluid(fluid: Fluid): void;
    /**
     * Removes the given fluid from the physics world.
     *
     * @param fluid The fluid to remove
     */
    removeFluid(fluid: Fluid): void;
    /**
     * Sets the gravity to use in the physics world.
     *
     * @param gravity The new gravity to use
     */
    setGravity(gravity: vec2): void;
    /**
     * Gets the gravity vector the physics world is using.
     *
     * @returns The gravity in use
     */
    getGravity(): vec2;
}
