export type PhysicsBodyDesc = {
    /**
     * - The body type: BODYTYPE_STATIC, BODYTYPE_DYNAMIC or
     * BODYTYPE_KINEMATIC.
     */
    type: string;
    /**
     * - The construction mass. Callers pass 0 for non-dynamic bodies.
     */
    mass: number;
    /**
     * - An opaque collision shape handle created by
     * {@link PhysicsWorld#createShape}.
     */
    shape: object;
    /**
     * - The initial world space position. Collision component offsets are
     * already applied by the caller.
     */
    position: Vec3;
    /**
     * - The initial world space rotation.
     */
    rotation: Quat;
    /**
     * - The entity this body simulates. Surfaced by raycast and
     * contact results.
     */
    entity: Entity | null;
    /**
     * - When true, the body collides and reports contacts
     * but does not respond to them (used for triggers). Defaults to false.
     */
    noContactResponse?: boolean;
};
export type PhysicsMeshSource = {
    /**
     * - A stable cache key for the source geometry (mesh id). Backends may
     * cache built triangle data per id for the lifetime of the world.
     */
    id: number;
    /**
     * - Vertex positions, possibly interleaved.
     */
    positions: Float32Array | number[];
    /**
     * - The number of floats between consecutive positions (3 when
     * tightly packed).
     */
    stride: number;
    /**
     * - Triangle indices. Ignored when
     * convexHull is true.
     */
    indices: number[] | Uint16Array | Uint32Array;
    /**
     * - The first index to read.
     */
    base: number;
    /**
     * - The number of indices to read (a multiple of 3). Ignored when
     * convexHull is true - hulls consume every position.
     */
    count: number;
    /**
     * - Build a convex hull instead of a triangle mesh.
     */
    convexHull: boolean;
    /**
     * - Weld duplicate vertices while building triangle data.
     */
    checkDuplicates: boolean;
    /**
     * - Scaling to bake into the positions while building, or null.
     */
    bakeScale: Vec3 | null;
    /**
     * - Scaling to apply to the built sub-shape, or null.
     */
    shapeScale: Vec3 | null;
    /**
     * - The sub-shape position within the mesh shape. Collision component
     * offsets are already applied by the caller.
     */
    position: Vec3;
    /**
     * - The sub-shape rotation within the mesh shape.
     */
    rotation: Quat;
};
export type PhysicsShapeDesc = {
    /**
     * - The shape type: 'box', 'sphere', 'capsule', 'cylinder', 'cone',
     * 'mesh' or 'compound'.
     */
    type: string;
    /**
     * - The box half extents.
     */
    halfExtents?: Vec3;
    /**
     * - The sphere/capsule/cylinder/cone radius.
     */
    radius?: number;
    /**
     * - The full capsule/cylinder/cone height along the alignment axis.
     * Backends convert to their own conventions.
     */
    height?: number;
    /**
     * - The capsule/cylinder/cone alignment axis: 0 (X), 1 (Y) or 2 (Z).
     */
    axis?: number;
    /**
     * - The geometry sources of a 'mesh' shape. Mesh
     * shapes are created in one atomic call so backends may build immutable composites.
     */
    sources?: PhysicsMeshSource[];
    /**
     * - Whole-shape scaling of a 'mesh' shape, or null.
     */
    scale?: Vec3 | null;
};
/**
 * The parameter bag consumed by {@link PhysicsWorld#createJoint} and the PhysicsJoint update
 * methods. JointComponent structurally satisfies this contract and passes itself.
 */
export type PhysicsJointSettings = {
    /**
     * - Whether hinge/slider limits are enabled.
     */
    enableLimits: boolean;
    /**
     * - The hinge (degrees) or slider (meters) limits.
     */
    limits: Vec2;
    /**
     * - The hinge (deg/s) or slider (m/s) motor speed.
     */
    motorSpeed: number;
    /**
     * - The maximum motor force. The motor is engaged while > 0.
     */
    maxMotorForce: number;
    /**
     * - The ball joint swing limit around Y in degrees.
     */
    swingLimitY: number;
    /**
     * - The ball joint swing limit around Z in degrees.
     */
    swingLimitZ: number;
    /**
     * - The ball joint twist limit in degrees.
     */
    twistLimit: number;
    /**
     * - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
     */
    linearMotionX: string;
    /**
     * - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
     */
    linearMotionY: string;
    /**
     * - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
     */
    linearMotionZ: string;
    /**
     * - The 6dof linear limits along X in meters.
     */
    linearLimitsX: Vec2;
    /**
     * - The 6dof linear limits along Y in meters.
     */
    linearLimitsY: Vec2;
    /**
     * - The 6dof linear limits along Z in meters.
     */
    linearLimitsZ: Vec2;
    /**
     * - The 6dof linear spring stiffness per axis.
     */
    linearStiffness: Vec3;
    /**
     * - The 6dof linear spring damping per axis.
     */
    linearDamping: Vec3;
    /**
     * - The 6dof linear spring equilibrium point per axis.
     */
    linearEquilibrium: Vec3;
    /**
     * - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
     */
    angularMotionX: string;
    /**
     * - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
     */
    angularMotionY: string;
    /**
     * - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
     */
    angularMotionZ: string;
    /**
     * - The 6dof angular limits around X in degrees.
     */
    angularLimitsX: Vec2;
    /**
     * - The 6dof angular limits around Y in degrees.
     */
    angularLimitsY: Vec2;
    /**
     * - The 6dof angular limits around Z in degrees.
     */
    angularLimitsZ: Vec2;
    /**
     * - The 6dof angular spring stiffness per axis.
     */
    angularStiffness: Vec3;
    /**
     * - The 6dof angular spring damping per axis.
     */
    angularDamping: Vec3;
    /**
     * - The 6dof angular spring equilibrium per axis in degrees.
     */
    angularEquilibrium: Vec3;
};
export type PhysicsJointDesc = {
    /**
     * - The joint type: JOINTTYPE_FIXED, JOINTTYPE_BALL, JOINTTYPE_HINGE,
     * JOINTTYPE_SLIDER or JOINTTYPE_6DOF.
     */
    type: string;
    /**
     * - The first constrained body.
     */
    bodyA: PhysicsBody;
    /**
     * - The second constrained body, or null to anchor the joint
     * to the world (the backend supplies its own fixed anchor body).
     */
    bodyB: PhysicsBody | null;
    /**
     * - The joint frame in body A's local space, as a scale-free matrix
     * with X as the primary joint axis by engine convention. Backends apply their own native axis
     * corrections. Only valid during the call.
     */
    frameA: Mat4;
    /**
     * - The joint frame in body B's local space (or world space when bodyB
     * is null).
     */
    frameB: Mat4;
    /**
     * - Whether the two bodies keep colliding with each other.
     * Creation-time only - changing it recreates the joint.
     */
    enableCollision: boolean;
    /**
     * - The full parameter bag, applied at creation.
     */
    settings: PhysicsJointSettings;
};
/**
 * A single contacting body pair reported to the {@link PhysicsContactListener}. Backends reuse
 * one instance per world - it is only valid inside onContactPair and must never be retained.
 */
export type PhysicsContactPair = {
    /**
     * - The entity owning the first body.
     */
    entityA: Entity;
    /**
     * - The entity owning the second body.
     */
    entityB: Entity;
    /**
     * - True if the first body has no contact response.
     */
    triggerA: boolean;
    /**
     * - True if the second body has no contact response.
     */
    triggerB: boolean;
    /**
     * - The number of contact points (always >= 1).
     */
    contactCount: number;
    /**
     * - Fills out with contact
     * point index from A's perspective, allocation free.
     */
    readContact: (index: number, out: ContactPoint) => void;
};
/**
 * Receives contact reports from a {@link PhysicsWorld}. The world runs one complete contact
 * pass - onContactsBegin, zero or more onContactPair, onContactsEnd - once per simulation
 * substep where the backend supports substep granularity, otherwise at least once per step.
 */
export type PhysicsContactListener = {
    /**
     * - Called when a contact pass begins.
     */
    onContactsBegin: () => void;
    /**
     * - Called for each contacting
     * pair. Pairs with no contact points or without entities on both bodies are not reported.
     */
    onContactPair: (pair: PhysicsContactPair) => void;
    /**
     * - Called when a contact pass ends.
     */
    onContactsEnd: () => void;
};
/**
 * @import { Entity } from '../entity.js'
 * @import { Mat4 } from '../../core/math/mat4.js'
 * @import { Quat } from '../../core/math/quat.js'
 * @import { Vec2 } from '../../core/math/vec2.js'
 * @import { Vec3 } from '../../core/math/vec3.js'
 * @import { ContactPoint } from '../components/rigid-body/contact-point.js'
 * @import { RaycastResult } from '../components/rigid-body/raycast-result.js'
 */
/**
 * @typedef {object} PhysicsBodyDesc
 * @property {string} type - The body type: BODYTYPE_STATIC, BODYTYPE_DYNAMIC or
 * BODYTYPE_KINEMATIC.
 * @property {number} mass - The construction mass. Callers pass 0 for non-dynamic bodies.
 * @property {object} shape - An opaque collision shape handle created by
 * {@link PhysicsWorld#createShape}.
 * @property {Vec3} position - The initial world space position. Collision component offsets are
 * already applied by the caller.
 * @property {Quat} rotation - The initial world space rotation.
 * @property {Entity|null} entity - The entity this body simulates. Surfaced by raycast and
 * contact results.
 * @property {boolean} [noContactResponse] - When true, the body collides and reports contacts
 * but does not respond to them (used for triggers). Defaults to false.
 * @ignore
 */
/**
 * @typedef {object} PhysicsMeshSource
 * @property {number} id - A stable cache key for the source geometry (mesh id). Backends may
 * cache built triangle data per id for the lifetime of the world.
 * @property {Float32Array|number[]} positions - Vertex positions, possibly interleaved.
 * @property {number} stride - The number of floats between consecutive positions (3 when
 * tightly packed).
 * @property {number[]|Uint16Array|Uint32Array} indices - Triangle indices. Ignored when
 * convexHull is true.
 * @property {number} base - The first index to read.
 * @property {number} count - The number of indices to read (a multiple of 3). Ignored when
 * convexHull is true - hulls consume every position.
 * @property {boolean} convexHull - Build a convex hull instead of a triangle mesh.
 * @property {boolean} checkDuplicates - Weld duplicate vertices while building triangle data.
 * @property {Vec3|null} bakeScale - Scaling to bake into the positions while building, or null.
 * @property {Vec3|null} shapeScale - Scaling to apply to the built sub-shape, or null.
 * @property {Vec3} position - The sub-shape position within the mesh shape. Collision component
 * offsets are already applied by the caller.
 * @property {Quat} rotation - The sub-shape rotation within the mesh shape.
 * @ignore
 */
/**
 * @typedef {object} PhysicsShapeDesc
 * @property {string} type - The shape type: 'box', 'sphere', 'capsule', 'cylinder', 'cone',
 * 'mesh' or 'compound'.
 * @property {Vec3} [halfExtents] - The box half extents.
 * @property {number} [radius] - The sphere/capsule/cylinder/cone radius.
 * @property {number} [height] - The full capsule/cylinder/cone height along the alignment axis.
 * Backends convert to their own conventions.
 * @property {number} [axis] - The capsule/cylinder/cone alignment axis: 0 (X), 1 (Y) or 2 (Z).
 * @property {PhysicsMeshSource[]} [sources] - The geometry sources of a 'mesh' shape. Mesh
 * shapes are created in one atomic call so backends may build immutable composites.
 * @property {Vec3|null} [scale] - Whole-shape scaling of a 'mesh' shape, or null.
 * @ignore
 */
/**
 * The parameter bag consumed by {@link PhysicsWorld#createJoint} and the PhysicsJoint update
 * methods. JointComponent structurally satisfies this contract and passes itself.
 *
 * @typedef {object} PhysicsJointSettings
 * @property {boolean} enableLimits - Whether hinge/slider limits are enabled.
 * @property {Vec2} limits - The hinge (degrees) or slider (meters) limits.
 * @property {number} motorSpeed - The hinge (deg/s) or slider (m/s) motor speed.
 * @property {number} maxMotorForce - The maximum motor force. The motor is engaged while > 0.
 * @property {number} swingLimitY - The ball joint swing limit around Y in degrees.
 * @property {number} swingLimitZ - The ball joint swing limit around Z in degrees.
 * @property {number} twistLimit - The ball joint twist limit in degrees.
 * @property {string} linearMotionX - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
 * @property {string} linearMotionY - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
 * @property {string} linearMotionZ - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
 * @property {Vec2} linearLimitsX - The 6dof linear limits along X in meters.
 * @property {Vec2} linearLimitsY - The 6dof linear limits along Y in meters.
 * @property {Vec2} linearLimitsZ - The 6dof linear limits along Z in meters.
 * @property {Vec3} linearStiffness - The 6dof linear spring stiffness per axis.
 * @property {Vec3} linearDamping - The 6dof linear spring damping per axis.
 * @property {Vec3} linearEquilibrium - The 6dof linear spring equilibrium point per axis.
 * @property {string} angularMotionX - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
 * @property {string} angularMotionY - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
 * @property {string} angularMotionZ - MOTION_FREE, MOTION_LIMITED or MOTION_LOCKED.
 * @property {Vec2} angularLimitsX - The 6dof angular limits around X in degrees.
 * @property {Vec2} angularLimitsY - The 6dof angular limits around Y in degrees.
 * @property {Vec2} angularLimitsZ - The 6dof angular limits around Z in degrees.
 * @property {Vec3} angularStiffness - The 6dof angular spring stiffness per axis.
 * @property {Vec3} angularDamping - The 6dof angular spring damping per axis.
 * @property {Vec3} angularEquilibrium - The 6dof angular spring equilibrium per axis in degrees.
 * @ignore
 */
/**
 * @typedef {object} PhysicsJointDesc
 * @property {string} type - The joint type: JOINTTYPE_FIXED, JOINTTYPE_BALL, JOINTTYPE_HINGE,
 * JOINTTYPE_SLIDER or JOINTTYPE_6DOF.
 * @property {PhysicsBody} bodyA - The first constrained body.
 * @property {PhysicsBody|null} bodyB - The second constrained body, or null to anchor the joint
 * to the world (the backend supplies its own fixed anchor body).
 * @property {Mat4} frameA - The joint frame in body A's local space, as a scale-free matrix
 * with X as the primary joint axis by engine convention. Backends apply their own native axis
 * corrections. Only valid during the call.
 * @property {Mat4} frameB - The joint frame in body B's local space (or world space when bodyB
 * is null).
 * @property {boolean} enableCollision - Whether the two bodies keep colliding with each other.
 * Creation-time only - changing it recreates the joint.
 * @property {PhysicsJointSettings} settings - The full parameter bag, applied at creation.
 * @ignore
 */
/**
 * A single contacting body pair reported to the {@link PhysicsContactListener}. Backends reuse
 * one instance per world - it is only valid inside onContactPair and must never be retained.
 *
 * @typedef {object} PhysicsContactPair
 * @property {Entity} entityA - The entity owning the first body.
 * @property {Entity} entityB - The entity owning the second body.
 * @property {boolean} triggerA - True if the first body has no contact response.
 * @property {boolean} triggerB - True if the second body has no contact response.
 * @property {number} contactCount - The number of contact points (always >= 1).
 * @property {(index: number, out: ContactPoint) => void} readContact - Fills out with contact
 * point index from A's perspective, allocation free.
 * @ignore
 */
/**
 * Receives contact reports from a {@link PhysicsWorld}. The world runs one complete contact
 * pass - onContactsBegin, zero or more onContactPair, onContactsEnd - once per simulation
 * substep where the backend supports substep granularity, otherwise at least once per step.
 *
 * @typedef {object} PhysicsContactListener
 * @property {() => void} onContactsBegin - Called when a contact pass begins.
 * @property {(pair: PhysicsContactPair) => void} onContactPair - Called for each contacting
 * pair. Pairs with no contact points or without entities on both bodies are not reported.
 * @property {() => void} onContactsEnd - Called when a contact pass ends.
 * @ignore
 */
/**
 * The base class for physics backends. A PhysicsWorld owns the lifecycle of a physics engine's
 * simulation world: stepping, gravity, body and shape factories, joints, raycasts and contact
 * reporting. Backends subclass it (AmmoPhysicsWorld) and override every method.
 *
 * The base implementation is a functional no-op: bodies and joints are created but inert,
 * raycasts miss and stepping does nothing. NullPhysicsWorld uses this to let component
 * lifecycle run in tests without a physics engine loaded.
 *
 * @ignore
 */
export class PhysicsWorld {
    /**
     * Create a new PhysicsWorld instance.
     *
     * @param {object} [options] - The world options.
     * @param {PhysicsContactListener} [options.contactListener] - The contact listener.
     */
    constructor(options?: {
        contactListener?: PhysicsContactListener;
    });
    /**
     * The listener driven during {@link PhysicsWorld#step}. Set once at construction.
     *
     * @type {PhysicsContactListener|null}
     */
    contactListener: PhysicsContactListener | null;
    /**
     * The backend-native world object - btDiscreteDynamicsWorld when the Ammo backend is
     * active, null otherwise.
     *
     * @type {object|null}
     */
    nativeWorld: object | null;
    /**
     * Destroys the world and all native resources it owns. The world is unusable afterwards.
     */
    destroy(): void;
    /**
     * Applies gravity if it differs from the current world gravity. Safe (and expected) to be
     * called every frame - backends deduplicate.
     *
     * @param {Vec3} gravity - The world space gravity.
     */
    setGravity(gravity: Vec3): void;
    /**
     * Advances the simulation. Contact passes are driven from inside this call on backends
     * that support substep granularity.
     *
     * @param {number} dt - The elapsed time in seconds.
     * @param {number} maxSubSteps - The maximum number of fixed substeps to take.
     * @param {number} fixedTimeStep - The duration of a fixed substep in seconds.
     */
    step(dt: number, maxSubSteps: number, fixedTimeStep: number): void;
    /**
     * Runs a deferred contact pass on backends that could not report contacts from inside
     * {@link PhysicsWorld#step}. Called by the system after dynamic transform sync. No-op on
     * backends that report during step.
     */
    flushContacts(): void;
    /**
     * Creates a body outside the simulation. Add it with {@link PhysicsWorld#addBody}.
     *
     * @param {PhysicsBodyDesc} desc - The body descriptor.
     * @returns {PhysicsBody} The new body.
     */
    createBody(desc: PhysicsBodyDesc): PhysicsBody;
    /**
     * Destroys a body. It must not currently be in the simulation.
     *
     * @param {PhysicsBody} body - The body to destroy.
     */
    destroyBody(body: PhysicsBody): void;
    /**
     * Adds a body to the simulation and applies the backend's activation policy for the body's
     * type (kinematic bodies never deactivate, all others enter the active state).
     *
     * @param {PhysicsBody} body - The body to add.
     * @param {number} [group] - The collision group bits. Used together with mask.
     * @param {number} [mask] - The collision mask bits.
     */
    addBody(body: PhysicsBody, group?: number, mask?: number): void;
    /**
     * Removes a body from the simulation. The body becomes inert until re-added.
     *
     * @param {PhysicsBody} body - The body to remove.
     */
    removeBody(body: PhysicsBody): void;
    /**
     * Creates a collision shape from a typed descriptor. The returned handle is opaque - it is
     * owned by this world and must only be passed back to this world.
     *
     * @param {PhysicsShapeDesc} desc - The shape descriptor.
     * @returns {object} The opaque shape handle.
     */
    createShape(desc: PhysicsShapeDesc): object;
    /**
     * Destroys a shape handle created by {@link PhysicsWorld#createShape}.
     *
     * @param {object} shape - The shape handle.
     */
    destroyShape(shape: object): void;
    /**
     * Adds a child shape to a 'compound' shape at a local pose.
     *
     * @param {object} compound - The compound shape handle.
     * @param {object} child - The child shape handle.
     * @param {Vec3} position - The child position in the compound's local space.
     * @param {Quat} rotation - The child rotation in the compound's local space.
     */
    addCompoundChild(compound: object, child: object, position: Vec3, rotation: Quat): void;
    /**
     * Updates the local pose of a child within a 'compound' shape. Adds the child if it is not
     * present.
     *
     * @param {object} compound - The compound shape handle.
     * @param {object} child - The child shape handle.
     * @param {Vec3} position - The child position in the compound's local space.
     * @param {Quat} rotation - The child rotation in the compound's local space.
     */
    updateCompoundChild(compound: object, child: object, position: Vec3, rotation: Quat): void;
    /**
     * Removes a child from a 'compound' shape. No-op if the child is not present.
     *
     * @param {object} compound - The compound shape handle.
     * @param {object} child - The child shape handle.
     */
    removeCompoundChild(compound: object, child: object): void;
    /**
     * Returns the number of children in a 'compound' shape.
     *
     * @param {object} compound - The compound shape handle.
     * @returns {number} The child count.
     */
    getCompoundChildCount(compound: object): number;
    /**
     * Creates a joint between two bodies (or one body and the world) and adds it to the
     * simulation.
     *
     * @param {PhysicsJointDesc} desc - The joint descriptor.
     * @returns {PhysicsJoint} The new joint.
     */
    createJoint(desc: PhysicsJointDesc): PhysicsJoint;
    /**
     * Removes a joint from the simulation and destroys it.
     *
     * @param {PhysicsJoint} joint - The joint to destroy.
     */
    destroyJoint(joint: PhysicsJoint): void;
    /**
     * Raycast the world and return the first hit.
     *
     * @param {Vec3} start - The world space start point.
     * @param {Vec3} end - The world space end point.
     * @param {object} [options] - The raycast options.
     * @param {number} [options.filterCollisionGroup] - Collision group to apply to the raycast.
     * @param {number} [options.filterCollisionMask] - Collision mask to apply to the raycast.
     * @returns {RaycastResult|null} The hit, or null if there was none.
     */
    raycastFirst(start: Vec3, end: Vec3, options?: {
        filterCollisionGroup?: number;
        filterCollisionMask?: number;
    }): RaycastResult | null;
    /**
     * Raycast the world and return all hits, in backend order.
     *
     * @param {Vec3} start - The world space start point.
     * @param {Vec3} end - The world space end point.
     * @param {object} [options] - The raycast options.
     * @param {number} [options.filterCollisionGroup] - Collision group to apply to the raycast.
     * @param {number} [options.filterCollisionMask] - Collision mask to apply to the raycast.
     * @param {any[]} [options.filterTags] - Tags filters. Defined the same way as a
     * {@link Tags#has} query but within an array. Hits filtered here are never allocated.
     * @param {Function} [options.filterCallback] - Custom function to use to filter entities.
     * Must return true to proceed with result. Takes the entity to evaluate as argument.
     * @returns {RaycastResult[]} The hits (0 length if there were none).
     */
    raycastAll(start: Vec3, end: Vec3, options?: {
        filterCollisionGroup?: number;
        filterCollisionMask?: number;
        filterTags?: any[];
        filterCallback?: Function;
    }): RaycastResult[];
}
import type { Vec3 } from '../../core/math/vec3.js';
import type { Quat } from '../../core/math/quat.js';
import type { Entity } from '../entity.js';
import type { Vec2 } from '../../core/math/vec2.js';
import { PhysicsBody } from './physics-body.js';
import type { Mat4 } from '../../core/math/mat4.js';
import type { ContactPoint } from '../components/rigid-body/contact-point.js';
import { PhysicsJoint } from './physics-joint.js';
import type { RaycastResult } from '../components/rigid-body/raycast-result.js';
