UNPKG

planck-js

Version:

2D JavaScript/TypeScript physics engine for cross-platform HTML5 game development

1,600 lines (1,599 loc) 135 kB
// Generated by dts-bundle-generator v9.5.1 /** 2D vector */ export interface Vec2Value { x: number; y: number; } /** @hidden @deprecated Use new keyword. */ export function Vec2(x: number, y: number): Vec2; /** @hidden @deprecated Use new keyword. */ export function Vec2(obj: Vec2Value): Vec2; /** @hidden @deprecated Use new keyword. */ export function Vec2(): Vec2; /** 2D vector */ export declare class Vec2 { x: number; y: number; constructor(x: number, y: number); constructor(obj: Vec2Value); constructor(); static zero(): Vec2; /** @hidden */ static neo(x: number, y: number): Vec2; static clone(v: Vec2Value): Vec2; /** @hidden */ toString(): string; /** * Does this vector contain finite coordinates? */ static isValid(obj: any): boolean; static assert(o: any): void; clone(): Vec2; /** * Set this vector to all zeros. * * @returns this */ setZero(): Vec2; set(x: number, y: number): Vec2; set(value: Vec2Value): Vec2; /** * Set this vector to some specified coordinates. * * @returns this */ setNum(x: number, y: number): this; /** * Set this vector to some specified coordinates. * * @returns this */ setVec2(value: Vec2Value): this; /** * Set linear combination of v and w: `a * v + b * w` */ setCombine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2; setMul(a: number, v: Vec2Value): Vec2; /** * Add a vector to this vector. * * @returns this */ add(w: Vec2Value): Vec2; /** * Add linear combination of v and w: `a * v + b * w` */ addCombine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2; addMul(a: number, v: Vec2Value): Vec2; /** * @deprecated Use subCombine or subMul */ wSub(a: number, v: Vec2Value, b?: number, w?: Vec2Value): Vec2; /** * Subtract linear combination of v and w: `a * v + b * w` */ subCombine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2; subMul(a: number, v: Vec2Value): Vec2; /** * Subtract a vector from this vector * * @returns this */ sub(w: Vec2Value): Vec2; /** * Multiply this vector by a scalar. * * @returns this */ mul(m: number): Vec2; /** * Get the length of this vector (the norm). * * For performance, use this instead of lengthSquared (if possible). */ length(): number; /** * Get the length squared. */ lengthSquared(): number; /** * Convert this vector into a unit vector. * * @returns old length */ normalize(): number; /** * Returns a new unit vector from the provided vector. * * @returns new unit vector */ static normalize(v: Vec2Value): Vec2; /** * Get the length of this vector (the norm). * * For performance, use this instead of lengthSquared (if possible). */ static lengthOf(v: Vec2Value): number; /** * Get the length squared. */ static lengthSquared(v: Vec2Value): number; static distance(v: Vec2Value, w: Vec2Value): number; static distanceSquared(v: Vec2Value, w: Vec2Value): number; static areEqual(v: Vec2Value, w: Vec2Value): boolean; /** * Get the skew vector such that dot(skew_vec, other) == cross(vec, other) */ static skew(v: Vec2Value): Vec2; /** Dot product on two vectors */ static dot(v: Vec2Value, w: Vec2Value): number; /** Cross product between two vectors */ static cross(v: Vec2Value, w: Vec2Value): number; /** Cross product between a vector and a scalar */ static cross(v: Vec2Value, w: number): Vec2; /** Cross product between a scalar and a vector */ static cross(v: number, w: Vec2Value): Vec2; /** Cross product on two vectors */ static crossVec2Vec2(v: Vec2Value, w: Vec2Value): number; /** Cross product on a vector and a scalar */ static crossVec2Num(v: Vec2Value, w: number): Vec2; /** Cross product on a vector and a scalar */ static crossNumVec2(v: number, w: Vec2Value): Vec2; /** Returns `a + (v x w)` */ static addCross(a: Vec2Value, v: Vec2Value, w: number): Vec2; /** Returns `a + (v x w)` */ static addCross(a: Vec2Value, v: number, w: Vec2Value): Vec2; /** * Returns `a + (v x w)` */ static addCrossVec2Num(a: Vec2Value, v: Vec2Value, w: number): Vec2; /** * Returns `a + (v x w)` */ static addCrossNumVec2(a: Vec2Value, v: number, w: Vec2Value): Vec2; static add(v: Vec2Value, w: Vec2Value): Vec2; /** @hidden @deprecated */ static wAdd(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2; static combine(a: number, v: Vec2Value, b: number, w: Vec2Value): Vec2; static sub(v: Vec2Value, w: Vec2Value): Vec2; static mul(a: Vec2Value, b: number): Vec2; static mul(a: number, b: Vec2Value): Vec2; static mulVec2Num(a: Vec2Value, b: number): Vec2; static mulNumVec2(a: number, b: Vec2Value): Vec2; neg(): Vec2; static neg(v: Vec2Value): Vec2; static abs(v: Vec2Value): Vec2; static mid(v: Vec2Value, w: Vec2Value): Vec2; static upper(v: Vec2Value, w: Vec2Value): Vec2; static lower(v: Vec2Value, w: Vec2Value): Vec2; clamp(max: number): Vec2; static clamp(v: Vec2Value, max: number): Vec2; /** @hidden */ static clampVec2(v: Vec2Value, min?: Vec2Value, max?: Vec2Value): Vec2Value; /** @hidden @deprecated */ static scaleFn(x: number, y: number): (v: Vec2Value) => Vec2; /** @hidden @deprecated */ static translateFn(x: number, y: number): (v: Vec2Value) => Vec2; } export interface RotValue { /** sin(angle) */ s: number; /** cos(angle) */ c: number; } /** @hidden @deprecated Use new keyword. */ export function Rot(angle: number): Rot; /** @hidden @deprecated Use new keyword. */ export function Rot(obj: RotValue): Rot; /** @hidden @deprecated Use new keyword. */ export function Rot(): Rot; /** Rotation */ export declare class Rot { /** sin(angle) */ s: number; /** cos(angle) */ c: number; /** Initialize from an angle in radians. */ constructor(angle?: number | RotValue); /** @hidden */ static neo(angle: number): Rot; static clone(rot: RotValue): Rot; static identity(): Rot; static isValid(obj: any): boolean; static assert(o: any): void; /** Set to the identity rotation. */ setIdentity(): void; set(angle: number | RotValue): void; setRot(angle: RotValue): void; /** Set using an angle in radians. */ setAngle(angle: number): void; /** Get the angle in radians. */ getAngle(): number; /** Get the x-axis. */ getXAxis(): Vec2; /** Get the y-axis. */ getYAxis(): Vec2; /** Multiply two rotations: q * r */ static mul(rot: RotValue, m: RotValue): Rot; /** Rotate a vector */ static mul(rot: RotValue, m: Vec2Value): Vec2; /** Multiply two rotations: q * r */ static mulRot(rot: RotValue, m: RotValue): Rot; /** Rotate a vector */ static mulVec2(rot: RotValue, m: Vec2Value): Vec2; static mulSub(rot: RotValue, v: Vec2Value, w: Vec2Value): Vec2; /** Transpose multiply two rotations: qT * r */ static mulT(rot: RotValue, m: RotValue): Rot; /** Inverse rotate a vector */ static mulT(rot: RotValue, m: Vec2Value): Vec2; /** Transpose multiply two rotations: qT * r */ static mulTRot(rot: RotValue, m: RotValue): Rot; /** Inverse rotate a vector */ static mulTVec2(rot: RotValue, m: Vec2Value): Vec2; } export type TransformValue = { p: Vec2Value; q: RotValue; }; /** @hidden @deprecated Use new keyword. */ export function Transform(position?: Vec2Value, rotation?: number): Transform; /** * A transform contains translation and rotation. It is used to represent the * position and orientation of rigid frames. Initialize using a position vector * and a rotation. */ export declare class Transform { /** position */ p: Vec2; /** rotation */ q: Rot; constructor(position?: Vec2Value, rotation?: number); static clone(xf: Transform): Transform; /** @hidden */ static neo(position: Vec2Value, rotation: Rot): Transform; static identity(): Transform; /** Set this to the identity transform */ setIdentity(): void; /** Set position and angle */ set(position: Vec2Value, rotation: number): void; /** Copy from another transform */ set(xf: TransformValue): void; /** Set position and angle */ setNum(position: Vec2Value, rotation: number): void; setTransform(xf: TransformValue): void; static isValid(obj: any): boolean; static assert(o: any): void; static mul(a: TransformValue, b: Vec2Value): Vec2; static mul(a: TransformValue, b: TransformValue): Transform; static mulAll(a: Transform, b: Vec2Value[]): Vec2[]; static mulAll(a: Transform, b: Transform[]): Transform[]; /** @hidden @deprecated */ static mulFn(a: TransformValue): (b: Vec2Value) => Vec2; static mulVec2(a: TransformValue, b: Vec2Value): Vec2; static mulXf(a: TransformValue, b: TransformValue): Transform; static mulT(a: TransformValue, b: Vec2Value): Vec2; static mulT(a: TransformValue, b: TransformValue): Transform; static mulTVec2(a: TransformValue, b: Vec2Value): Vec2; static mulTXf(a: TransformValue, b: TransformValue): Transform; } /** * Ray-cast input data. The ray extends from `p1` to `p1 + maxFraction * (p2 - p1)`. */ export interface RayCastInput { p1: Vec2Value; p2: Vec2Value; maxFraction: number; } export type RayCastCallback = (subInput: RayCastInput, id: number) => number; /** * Ray-cast output data. The ray hits at `p1 + fraction * (p2 - p1)`, * where `p1` and `p2` come from RayCastInput. */ export interface RayCastOutput { normal: Vec2; fraction: number; } /** Axis-aligned bounding box */ export interface AABBValue { lowerBound: Vec2Value; upperBound: Vec2Value; } /** @hidden @deprecated Use new keyword. */ export function AABB(lower?: Vec2Value, upper?: Vec2Value): AABB; /** Axis-aligned bounding box */ export declare class AABB { lowerBound: Vec2; upperBound: Vec2; constructor(lower?: Vec2Value, upper?: Vec2Value); /** * Verify that the bounds are sorted. */ isValid(): boolean; static isValid(obj: any): boolean; static assert(o: any): void; /** * Get the center of the AABB. */ getCenter(): Vec2; /** * Get the extents of the AABB (half-widths). */ getExtents(): Vec2; /** * Get the perimeter length. */ getPerimeter(): number; /** * Combine one or two AABB into this one. */ combine(a: AABBValue, b?: AABBValue): void; combinePoints(a: Vec2Value, b: Vec2Value): void; set(aabb: AABBValue): void; contains(aabb: AABBValue): boolean; extend(value: number): AABB; static extend(out: AABBValue, value: number): AABBValue; static testOverlap(a: AABBValue, b: AABBValue): boolean; static areEqual(a: AABBValue, b: AABBValue): boolean; static diff(a: AABBValue, b: AABBValue): number; rayCast(output: RayCastOutput, input: RayCastInput): boolean; /** @hidden */ toString(): string; static combinePoints(out: AABBValue, a: Vec2Value, b: Vec2Value): AABBValue; static combinedPerimeter(a: AABBValue, b: AABBValue): number; } /** * Input for Distance. You have to option to use the shape radii in the * computation. Even */ export declare class DistanceInput { readonly proxyA: DistanceProxy; readonly proxyB: DistanceProxy; readonly transformA: Transform; readonly transformB: Transform; useRadii: boolean; recycle(): void; } /** * Output for Distance. */ export declare class DistanceOutput { /** closest point on shapeA */ pointA: Vec2Value; /** closest point on shapeB */ pointB: Vec2Value; distance: number; /** iterations number of GJK iterations used */ iterations: number; recycle(): void; } /** * Used to warm start Distance. Set count to zero on first call. */ export declare class SimplexCache { /** length or area */ metric: number; /** vertices on shape A */ indexA: number[]; /** vertices on shape B */ indexB: number[]; count: number; recycle(): void; } /** * Compute the closest points between two shapes. Supports any combination of: * CircleShape, PolygonShape, EdgeShape. The simplex cache is input/output. On * the first call set SimplexCache.count to zero. */ export declare const Distance: { (output: DistanceOutput, cache: SimplexCache, input: DistanceInput): void; testOverlap: (shapeA: Shape, indexA: number, shapeB: Shape, indexB: number, xfA: TransformValue, xfB: TransformValue) => boolean; Input: typeof DistanceInput; Output: typeof DistanceOutput; Proxy: typeof DistanceProxy; Cache: typeof SimplexCache; }; /** * A distance proxy is used by the GJK algorithm. It encapsulates any shape. */ export declare class DistanceProxy { recycle(): void; /** * Get the vertex count. */ getVertexCount(): number; /** * Get a vertex by index. Used by Distance. */ getVertex(index: number): Vec2Value; /** * Get the supporting vertex index in the given direction. */ getSupport(d: Vec2Value): number; /** * Get the supporting vertex in the given direction. */ getSupportVertex(d: Vec2Value): Vec2Value; /** * Initialize the proxy using the given shape. The shape must remain in scope * while the proxy is in use. */ set(shape: Shape, index: number): void; /** * Initialize the proxy using a vertex cloud and radius. The vertices * must remain in scope while the proxy is in use. */ setVertices(vertices: Vec2Value[], count: number, radius: number): void; } /** * Determine if two generic shapes overlap. */ export declare const testOverlap: (shapeA: Shape, indexA: number, shapeB: Shape, indexB: number, xfA: TransformValue, xfB: TransformValue) => boolean; /** * Input parameters for ShapeCast */ export declare class ShapeCastInput { readonly proxyA: DistanceProxy; readonly proxyB: DistanceProxy; readonly transformA: Transform; readonly transformB: Transform; readonly translationB: Vec2; recycle(): void; } /** * Output results for b2ShapeCast */ export declare class ShapeCastOutput { point: Vec2; normal: Vec2; lambda: number; iterations: number; } /** * Perform a linear shape cast of shape B moving and shape A fixed. Determines * the hit point, normal, and translation fraction. * * @returns true if hit, false if there is no hit or an initial overlap */ export declare const ShapeCast: (output: ShapeCastOutput, input: ShapeCastInput) => boolean; /** * A joint edge is used to connect bodies and joints together in a joint graph * where each body is a node and each joint is an edge. A joint edge belongs to * a doubly linked list maintained in each attached body. Each joint has two * joint nodes, one for each attached body. */ export declare class JointEdge { /** * provides quick access to the other body attached. */ other: Body$1 | null; /** * the joint */ joint: Joint | null; /** * prev the previous joint edge in the body's joint list */ prev: JointEdge | null; /** * the next joint edge in the body's joint list */ next: JointEdge | null; } /** * Joint definitions are used to construct joints. */ export interface JointOpt { /** * Use this to attach application specific data to your joints. */ userData?: any; /** * Set this flag to true if the attached bodies * should collide. */ collideConnected?: boolean; /** Styling for dev-tools. */ style?: Style; } /** * Joint definitions are used to construct joints. */ export interface JointDef extends JointOpt { /** * The first attached body. */ bodyA: Body$1; /** * The second attached body. */ bodyB: Body$1; } /** * The base joint class. Joints are used to constraint two bodies together in * various fashions. Some joints also feature limits and motors. */ export declare abstract class Joint { /** Styling for dev-tools. */ style: Style; /** @hidden @experimental Similar to userData, but used by dev-tools or runtime environment. */ appData: Record<string, any>; constructor(def: JointDef); constructor(def: JointOpt, bodyA: Body$1, bodyB: Body$1); /** * Short-cut function to determine if either body is inactive. */ isActive(): boolean; /** * Get the type of the concrete joint. */ getType(): string; /** * Get the first body attached to this joint. */ getBodyA(): Body$1; /** * Get the second body attached to this joint. */ getBodyB(): Body$1; /** * Get the next joint the world joint list. */ getNext(): Joint; getUserData(): unknown; setUserData(data: unknown): void; /** * Get collide connected. Note: modifying the collide connect flag won't work * correctly because the flag is only checked when fixture AABBs begin to * overlap. */ getCollideConnected(): boolean; /** * Get the anchor point on bodyA in world coordinates. */ abstract getAnchorA(): Vec2; /** * Get the anchor point on bodyB in world coordinates. */ abstract getAnchorB(): Vec2; /** * Get the reaction force on bodyB at the joint anchor in Newtons. */ abstract getReactionForce(inv_dt: number): Vec2; /** * Get the reaction torque on bodyB in N*m. */ abstract getReactionTorque(inv_dt: number): number; /** * Shift the origin for any points stored in world coordinates. */ shiftOrigin(newOrigin: Vec2Value): void; abstract initVelocityConstraints(step: TimeStep): void; abstract solveVelocityConstraints(step: TimeStep): void; /** * This returns true if the position errors are within tolerance. */ abstract solvePositionConstraints(step: TimeStep): boolean; /** * @hidden @experimental * Update joint with new props. */ abstract _reset(def: Partial<JointDef>): void; } export interface Style { stroke?: string; fill?: string; lineWidth?: number; } export type KEY = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" | "right" | "left" | "up" | "down" | "fire"; export type ActiveKeys = { [key in KEY]?: boolean; }; export type TestbedMountOptions = { [key: string]: any; }; export declare abstract class Testbed { /** * Mounts testbed. Call start with a world to start simulation and rendering. */ static mount(options?: TestbedMountOptions): Testbed; /** * Mounts testbed if needed, then starts simulation and rendering. * * If you need to customize testbed before starting, first run `const testbed = Testbed.mount()` and then `testbed.start()`. */ static start(world: World): Testbed; /** World viewbox width. */ width: number; /** World viewbox height. */ height: number; /** World viewbox center vertical offset. */ x: number; /** World viewbox center horizontal offset. */ y: number; /** @hidden */ scaleY: number; /** World simulation step frequency */ hz: number; /** World simulation speed, default is 1 */ speed: number; background: string; mouseForce?: number; activeKeys: ActiveKeys; /** callback, to be implemented by user */ step: (dt: number, t: number) => void; /** callback, to be implemented by user */ keydown: (keyCode: number, label: string) => void; /** callback, to be implemented by user */ keyup: (keyCode: number, label: string) => void; abstract status(name: string, value: any): void; abstract status(value: object | string): void; abstract info(text: string): void; color(r: number, g: number, b: number): string; abstract drawPoint(p: { x: number; y: number; }, r: any, color: string): void; abstract drawCircle(p: { x: number; y: number; }, r: number, color: string): void; abstract drawEdge(a: { x: number; y: number; }, b: { x: number; y: number; }, color: string): void; abstract drawSegment(a: { x: number; y: number; }, b: { x: number; y: number; }, color: string): void; abstract drawPolygon(points: Array<{ x: number; y: number; }>, color: string): void; abstract drawAABB(aabb: AABBValue, color: string): void; abstract start(world: World): void; abstract findOne(query: string): (Body$1 | Joint | Fixture | null); abstract findAll(query: string): (Body$1 | Joint | Fixture)[]; } export type TestbedFactoryOptions = string | TestbedMountOptions; /** @deprecated */ export type TestbedCallback = (testbed: Testbed) => (World | undefined); /** @deprecated */ export declare function testbed(callback: TestbedCallback): void; /** @deprecated */ export declare function testbed(options: TestbedFactoryOptions, callback: TestbedCallback): void; /** * A shape is used for collision detection. You can create a shape however you * like. Shapes used for simulation in World are created automatically when a * Fixture is created. Shapes may encapsulate one or more child shapes. */ export declare abstract class Shape { /** @hidden */ m_type: ShapeType; /** * @hidden * Radius of a shape. For polygonal shapes this must be b2_polygonRadius. * There is no support for making rounded polygons. */ m_radius: number; /** Styling for dev-tools. */ style: Style; /** @hidden @experimental Similar to userData, but used by dev-tools or runtime environment. */ appData: Record<string, any>; /** @hidden */ abstract _reset(): void; static isValid(obj: any): boolean; abstract getRadius(): number; /** * Get the type of this shape. You can use this to down cast to the concrete * shape. * * @return the shape type. */ abstract getType(): ShapeType; /** * Get the number of child primitives. */ abstract getChildCount(): number; /** * Test a point for containment in this shape. This only works for convex * shapes. * * @param xf The shape world transform. * @param p A point in world coordinates. */ abstract testPoint(xf: TransformValue, p: Vec2Value): boolean; /** * Cast a ray against a child shape. * * @param output The ray-cast results. * @param input The ray-cast input parameters. * @param xf The transform to be applied to the shape. * @param childIndex The child shape index */ abstract rayCast(output: RayCastOutput, input: RayCastInput, xf: Transform, childIndex: number): boolean; /** * Given a transform, compute the associated axis aligned bounding box for a * child shape. * * @param aabb Returns the axis aligned box. * @param xf The world transform of the shape. * @param childIndex The child shape */ abstract computeAABB(aabb: AABBValue, xf: TransformValue, childIndex: number): void; /** * Compute the mass properties of this shape using its dimensions and density. * The inertia tensor is computed about the local origin. * * @param massData Returns the mass data for this shape. * @param density The density in kilograms per meter squared. */ abstract computeMass(massData: MassData, density?: number): void; abstract computeDistanceProxy(proxy: DistanceProxy, childIndex: number): void; } export type ShapeType = "circle" | "edge" | "polygon" | "chain"; export type DynamicTreeQueryCallback = (nodeId: number) => boolean; /** * A node in the dynamic tree. The client does not interact with this directly. */ export declare class TreeNode<T> { id: number; /** Enlarged AABB */ aabb: AABB; userData: T; parent: TreeNode<T>; child1: TreeNode<T>; child2: TreeNode<T>; /** 0: leaf, -1: free node */ height: number; constructor(id?: number); isLeaf(): boolean; } /** * A dynamic AABB tree broad-phase, inspired by Nathanael Presson's btDbvt. A * dynamic tree arranges data in a binary tree to accelerate queries such as * volume queries and ray casts. Leafs are proxies with an AABB. In the tree we * expand the proxy AABB by `aabbExtension` so that the proxy AABB is bigger * than the client object. This allows the client object to move by small * amounts without triggering a tree update. * * Nodes are pooled and relocatable, so we use node indices rather than * pointers. */ export declare class DynamicTree<T> { m_root: TreeNode<T>; m_lastProxyId: number; m_nodes: { [id: number]: TreeNode<T>; }; constructor(); /** * Get proxy user data. * * @return the proxy user data or 0 if the id is invalid. */ getUserData(id: number): T; /** * Get the fat AABB for a node id. * * @return the proxy user data or 0 if the id is invalid. */ getFatAABB(id: number): AABB; allocateNode(): TreeNode<T>; freeNode(node: TreeNode<T>): void; /** * Create a proxy in the tree as a leaf node. We return the index of the node * instead of a pointer so that we can grow the node pool. * * Create a proxy. Provide a tight fitting AABB and a userData pointer. */ createProxy(aabb: AABBValue, userData: T): number; /** * Destroy a proxy. This asserts if the id is invalid. */ destroyProxy(id: number): void; /** * Move a proxy with a swepted AABB. If the proxy has moved outside of its * fattened AABB, then the proxy is removed from the tree and re-inserted. * Otherwise the function returns immediately. * * @param d Displacement * * @return true if the proxy was re-inserted. */ moveProxy(id: number, aabb: AABBValue, d: Vec2Value): boolean; insertLeaf(leaf: TreeNode<T>): void; removeLeaf(leaf: TreeNode<T>): void; /** * Perform a left or right rotation if node A is imbalanced. Returns the new * root index. */ balance(iA: TreeNode<T>): TreeNode<T>; /** * Compute the height of the binary tree in O(N) time. Should not be called * often. */ getHeight(): number; /** * Get the ratio of the sum of the node areas to the root area. */ getAreaRatio(): number; /** * Compute the height of a sub-tree. */ computeHeight(id?: number): number; validateStructure(node: TreeNode<T>): void; validateMetrics(node: TreeNode<T>): void; /** * Validate this tree. For testing. */ validate(): void; /** * Get the maximum balance of an node in the tree. The balance is the difference * in height of the two children of a node. */ getMaxBalance(): number; /** * Build an optimal tree. Very expensive. For testing. */ rebuildBottomUp(): void; /** * Shift the world origin. Useful for large worlds. The shift formula is: * position -= newOrigin * * @param newOrigin The new origin with respect to the old origin */ shiftOrigin(newOrigin: Vec2Value): void; /** * Query an AABB for overlapping proxies. The callback class is called for each * proxy that overlaps the supplied AABB. */ query(aabb: AABBValue, queryCallback: DynamicTreeQueryCallback): void; /** * Ray-cast against the proxies in the tree. This relies on the callback to * perform a exact ray-cast in the case were the proxy contains a shape. The * callback also performs the any collision filtering. This has performance * roughly equal to k * log(n), where k is the number of collisions and n is the * number of proxies in the tree. * * @param input The ray-cast input data. The ray extends from `p1` to `p1 + maxFraction * (p2 - p1)`. * @param rayCastCallback A function that is called for each proxy that is hit by the ray. If the return value is a positive number it will update the maxFraction of the ray cast input, and if it is zero it will terminate they ray cast. */ rayCast(input: RayCastInput, rayCastCallback: RayCastCallback): void; private inputPool; private stackPool; private iteratorPool; } /** * The broad-phase wraps and extends a dynamic-tree to keep track of moved * objects and query them on update. */ export declare class BroadPhase { m_tree: DynamicTree<FixtureProxy>; m_moveBuffer: number[]; m_callback: (userDataA: any, userDataB: any) => void; m_queryProxyId: number; /** * Get user data from a proxy. Returns null if the id is invalid. */ getUserData(proxyId: number): FixtureProxy; /** * Test overlap of fat AABBs. */ testOverlap(proxyIdA: number, proxyIdB: number): boolean; /** * Get the fat AABB for a proxy. */ getFatAABB(proxyId: number): AABB; /** * Get the number of proxies. */ getProxyCount(): number; /** * Get the height of the embedded tree. */ getTreeHeight(): number; /** * Get the balance (integer) of the embedded tree. */ getTreeBalance(): number; /** * Get the quality metric of the embedded tree. */ getTreeQuality(): number; /** * Query an AABB for overlapping proxies. The callback class is called for each * proxy that overlaps the supplied AABB. */ query: (aabb: AABBValue, queryCallback: DynamicTreeQueryCallback) => void; /** * Ray-cast against the proxies in the tree. This relies on the callback to * perform a exact ray-cast in the case were the proxy contains a shape. The * callback also performs the any collision filtering. This has performance * roughly equal to k * log(n), where k is the number of collisions and n is the * number of proxies in the tree. * * @param input The ray-cast input data. The ray extends from `p1` to `p1 + maxFraction * (p2 - p1)`. * @param rayCastCallback A function that is called for each proxy that is hit by the ray. If the return value is a positive number it will update the maxFraction of the ray cast input, and if it is zero it will terminate they ray cast. */ rayCast(input: RayCastInput, rayCastCallback: RayCastCallback): void; /** * Shift the world origin. Useful for large worlds. The shift formula is: * position -= newOrigin * * @param newOrigin The new origin with respect to the old origin */ shiftOrigin(newOrigin: Vec2Value): void; /** * Create a proxy with an initial AABB. Pairs are not reported until UpdatePairs * is called. */ createProxy(aabb: AABBValue, userData: FixtureProxy): number; /** * Destroy a proxy. It is up to the client to remove any pairs. */ destroyProxy(proxyId: number): void; /** * Call moveProxy as many times as you like, then when you are done call * UpdatePairs to finalized the proxy pairs (for your time step). */ moveProxy(proxyId: number, aabb: AABB, displacement: Vec2Value): void; /** * Call to trigger a re-processing of it's pairs on the next call to * UpdatePairs. */ touchProxy(proxyId: number): void; bufferMove(proxyId: number): void; unbufferMove(proxyId: number): void; /** * Update the pairs. This results in pair callbacks. This can only add pairs. */ updatePairs(addPairCallback: (userDataA: FixtureProxy, userDataB: FixtureProxy) => void): void; queryCallback: (proxyId: number) => boolean; } /** * A fixture definition is used to create a fixture. This class defines an * abstract fixture definition. You can reuse fixture definitions safely. */ export interface FixtureOpt { userData?: unknown; /** * The friction coefficient, usually in the range [0,1] */ friction?: number; /** * The restitution (elasticity) usually in the range [0,1] */ restitution?: number; /** * The density, usually in kg/m^2 */ density?: number; /** * A sensor shape collects contact information but never generates a collision response. */ isSensor?: boolean; /** * Zero, positive or negative collision group. * Fixtures with same positive groupIndex always collide and fixtures with same negative groupIndex never collide. */ filterGroupIndex?: number; /** * Collision category bit or bits that this fixture belongs to. * If groupIndex is zero or not matching, then at least one bit in this fixture categoryBits should match other fixture maskBits and vice versa. */ filterCategoryBits?: number; /** * Collision category bit or bits that this fixture accept for collision. */ filterMaskBits?: number; /** Styling for dev-tools. */ style?: Style; } export interface FixtureDef extends FixtureOpt { shape: Shape; } /** * This proxy is used internally to connect shape children to the broad-phase. */ export declare class FixtureProxy { aabb: AABB; fixture: Fixture; childIndex: number; proxyId: number; constructor(fixture: Fixture, childIndex: number); } /** * A fixture is used to attach a shape to a body for collision detection. A * fixture inherits its transform from its parent. Fixtures hold additional * non-geometric data such as friction, collision filters, etc. * * To create a new Fixture use {@link Body.createFixture}. */ export declare class Fixture { /** Styling for dev-tools. */ style: Style; /** @hidden @experimental Similar to userData, but used by dev-tools or runtime environment. */ appData: Record<string, any>; constructor(body: Body$1, def: FixtureDef); constructor(body: Body$1, shape: Shape, def?: FixtureOpt); constructor(body: Body$1, shape: Shape, density?: number); /** @hidden Re-setup fixture. */ _reset(): void; /** * Get the type of the child shape. You can use this to down cast to the * concrete shape. */ getType(): ShapeType; /** * Get the child shape. You can modify the child shape, however you should not * change the number of vertices because this will crash some collision caching * mechanisms. Manipulating the shape may lead to non-physical behavior. */ getShape(): Shape; /** * A sensor shape collects contact information but never generates a collision * response. */ isSensor(): boolean; /** * Set if this fixture is a sensor. */ setSensor(sensor: boolean): void; /** * Get the user data that was assigned in the fixture definition. Use this to * store your application specific data. */ getUserData(): unknown; /** * Set the user data. Use this to store your application specific data. */ setUserData(data: unknown): void; /** * Get the parent body of this fixture. This is null if the fixture is not * attached. */ getBody(): Body$1; /** * Get the next fixture in the parent body's fixture list. */ getNext(): Fixture | null; /** * Get the density of this fixture. */ getDensity(): number; /** * Set the density of this fixture. This will _not_ automatically adjust the * mass of the body. You must call Body.resetMassData to update the body's mass. */ setDensity(density: number): void; /** * Get the coefficient of friction, usually in the range [0,1]. */ getFriction(): number; /** * Set the coefficient of friction. This will not change the friction of * existing contacts. */ setFriction(friction: number): void; /** * Get the coefficient of restitution. */ getRestitution(): number; /** * Set the coefficient of restitution. This will not change the restitution of * existing contacts. */ setRestitution(restitution: number): void; /** * Test a point in world coordinates for containment in this fixture. */ testPoint(p: Vec2Value): boolean; /** * Cast a ray against this shape. */ rayCast(output: RayCastOutput, input: RayCastInput, childIndex: number): boolean; /** * Get the mass data for this fixture. The mass data is based on the density and * the shape. The rotational inertia is about the shape's origin. This operation * may be expensive. */ getMassData(massData: MassData): void; /** * Get the fixture's AABB. This AABB may be enlarge and/or stale. If you need a * more accurate AABB, compute it using the shape and the body transform. */ getAABB(childIndex: number): AABB; /** * These support body activation/deactivation. */ createProxies(broadPhase: BroadPhase, xf: TransformValue): void; destroyProxies(broadPhase: BroadPhase): void; /** * Updates this fixture proxy in broad-phase (with combined AABB of current and * next transformation). */ synchronize(broadPhase: BroadPhase, xf1: TransformValue, xf2: TransformValue): void; /** * Set the contact filtering data. This will not update contacts until the next * time step when either parent body is active and awake. This automatically * calls refilter. */ setFilterData(filter: { groupIndex: number; categoryBits: number; maskBits: number; }): void; getFilterGroupIndex(): number; setFilterGroupIndex(groupIndex: number): void; getFilterCategoryBits(): number; setFilterCategoryBits(categoryBits: number): void; getFilterMaskBits(): number; setFilterMaskBits(maskBits: number): void; /** * Call this if you want to establish collision that was previously disabled by * ContactFilter. */ refilter(): void; /** * Implement this method to provide collision filtering, if you want finer * control over contact creation. * * Return true if contact calculations should be performed between these two * fixtures. * * Warning: for performance reasons this is only called when the AABBs begin to * overlap. */ shouldCollide(that: Fixture): boolean; } export declare enum ManifoldType { e_unset = -1, e_circles = 0, e_faceA = 1, e_faceB = 2 } export declare enum ContactFeatureType { e_unset = -1, e_vertex = 0, e_face = 1 } /** * This is used for determining the state of contact points. */ export declare enum PointState { /** Point does not exist */ nullState = 0, /** Point was added in the update */ addState = 1, /** Point persisted across the update */ persistState = 2, /** Point was removed in the update */ removeState = 3 } /** * Used for computing contact manifolds. */ export declare class ClipVertex { v: Vec2Value; id: ContactID; set(o: ClipVertex): void; recycle(): void; } /** * A manifold for two touching convex shapes. Manifolds are created in `evaluate` * method of Contact subclasses. * * Supported manifold types are e_faceA or e_faceB for clip point versus plane * with radius and e_circles point versus point with radius. * * We store contacts in this way so that position correction can account for * movement, which is critical for continuous physics. All contact scenarios * must be expressed in one of these types. This structure is stored across time * steps, so we keep it small. */ export declare class Manifold { type: ManifoldType; /** * Usage depends on manifold type: * - circles: not used * - faceA: the normal on polygonA * - faceB: the normal on polygonB */ localNormal: Vec2Value; /** * Usage depends on manifold type: * - circles: the local center of circleA * - faceA: the center of faceA * - faceB: the center of faceB */ localPoint: Vec2Value; /** The points of contact */ points: ManifoldPoint[]; /** The number of manifold points */ pointCount: number; set(that: Manifold): void; recycle(): void; /** * Evaluate the manifold with supplied transforms. This assumes modest motion * from the original state. This does not change the point count, impulses, etc. * The radii must come from the shapes that generated the manifold. */ getWorldManifold(wm: WorldManifold | null, xfA: TransformValue, radiusA: number, xfB: TransformValue, radiusB: number): WorldManifold; static clipSegmentToLine: typeof clipSegmentToLine; static ClipVertex: typeof ClipVertex; static getPointStates: typeof getPointStates; static PointState: typeof PointState; } /** * A manifold point is a contact point belonging to a contact manifold. It holds * details related to the geometry and dynamics of the contact points. * * This structure is stored across time steps, so we keep it small. * * Note: impulses are used for internal caching and may not provide reliable * contact forces, especially for high speed collisions. */ export declare class ManifoldPoint { /** * Usage depends on manifold type: * - circles: the local center of circleB * - faceA: the local center of circleB or the clip point of polygonB * - faceB: the clip point of polygonA */ localPoint: Vec2Value; /** * The non-penetration impulse */ normalImpulse: number; /** * The friction impulse */ tangentImpulse: number; /** * Uniquely identifies a contact point between two shapes to facilitate warm starting */ readonly id: ContactID; set(that: ManifoldPoint): void; recycle(): void; } /** * Contact ids to facilitate warm starting. * * ContactFeature: The features that intersect to form the contact point. */ export declare class ContactID { /** * Used to quickly compare contact ids. */ key: number; /** ContactFeature index on shapeA */ indexA: number; /** ContactFeature index on shapeB */ indexB: number; /** ContactFeature type on shapeA */ typeA: ContactFeatureType; /** ContactFeature type on shapeB */ typeB: ContactFeatureType; setFeatures(indexA: number, typeA: ContactFeatureType, indexB: number, typeB: ContactFeatureType): void; set(that: ContactID): void; swapFeatures(): void; recycle(): void; } /** * This is used to compute the current state of a contact manifold. */ export declare class WorldManifold { /** World vector pointing from A to B */ normal: Vec2Value; /** World contact point (point of intersection) */ points: Vec2Value[]; /** A negative value indicates overlap, in meters */ separations: number[]; /** The number of manifold points */ pointCount: number; recycle(): void; } /** * Compute the point states given two manifolds. The states pertain to the * transition from manifold1 to manifold2. So state1 is either persist or remove * while state2 is either add or persist. */ export declare function getPointStates(state1: PointState[], state2: PointState[], manifold1: Manifold, manifold2: Manifold): void; /** * Clipping for contact manifolds. Sutherland-Hodgman clipping. */ export declare function clipSegmentToLine(vOut: ClipVertex[], vIn: ClipVertex[], normal: Vec2Value, offset: number, vertexIndexA: number): number; /** * A contact edge is used to connect bodies and contacts together in a contact * graph where each body is a node and each contact is an edge. A contact edge * belongs to a doubly linked list maintained in each attached body. Each * contact has two contact nodes, one for each attached body. */ export declare class ContactEdge { contact: Contact; prev: ContactEdge | null; next: ContactEdge | null; other: Body$1 | null; constructor(contact: Contact); } export type EvaluateFunction = (manifold: Manifold, xfA: TransformValue, fixtureA: Fixture, indexA: number, xfB: TransformValue, fixtureB: Fixture, indexB: number) => void; /** * Friction mixing law. The idea is to allow either fixture to drive the * friction to zero. For example, anything slides on ice. */ export declare function mixFriction(friction1: number, friction2: number): number; /** * Restitution mixing law. The idea is allow for anything to bounce off an * inelastic surface. For example, a superball bounces on anything. */ export declare function mixRestitution(restitution1: number, restitution2: number): number; export declare class VelocityConstraintPoint { rA: Vec2Value; rB: Vec2Value; normalImpulse: number; tangentImpulse: number; normalMass: number; tangentMass: number; velocityBias: number; recycle(): void; } /** * The class manages contact between two shapes. A contact exists for each * overlapping AABB in the broad-phase (except if filtered). Therefore a contact * object may exist that has no contact points. */ export declare class Contact { initConstraint(step: TimeStep): void; /** * Get the contact manifold. Do not modify the manifold unless you understand * the internals of the library. */ getManifold(): Manifold; /** * Get the world manifold. */ getWorldManifold(worldManifold: WorldManifold | null): WorldManifold | undefined; /** * Enable/disable this contact. This can be used inside the pre-solve contact * listener. The contact is only disabled for the current time step (or sub-step * in continuous collisions). */ setEnabled(flag: boolean): void; /** * Has this contact been disabled? */ isEnabled(): boolean; /** * Is this contact touching? */ isTouching(): boolean; /** * Get the next contact in the world's contact list. */ getNext(): Contact | null; /** * Get fixture A in this contact. */ getFixtureA(): Fixture; /** * Get fixture B in this contact. */ getFixtureB(): Fixture; /** * Get the child primitive index for fixture A. */ getChildIndexA(): number; /** * Get the child primitive index for fixture B. */ getChildIndexB(): number; /** * Flag this contact for filtering. Filtering will occur the next time step. */ flagForFiltering(): void; /** * Override the default friction mixture. You can call this in * "pre-solve" callback. This value persists until set or reset. */ setFriction(friction: number): void; /** * Get the friction. */ getFriction(): number; /** * Reset the friction mixture to the default value. */ resetFriction(): void; /** * Override the default restitution mixture. You can call this in * "pre-solve" callback. The value persists until you set or reset. */ setRestitution(restitution: number): void; /** * Get the restitution. */ getRestitution(): number; /** * Reset the restitution to the default value. */ resetRestitution(): void; /** * Set the desired tangent speed for a conveyor belt behavior. In meters per * second. */ setTangentSpeed(speed: number): void; /** * Get the desired tangent speed. In meters per second. */ getTangentSpeed(): number; /** * Called by Update method, and implemented by subclasses. */ evaluate(manifold: Manifold, xfA: TransformValue, xfB: TransformValue): void; /** * Updates the contact manifold and touching status. * * Note: do not assume the fixture AABBs are overlapping or are valid. * * @param listener.beginContact * @param listener.endContact * @param listener.preSolve */ update(listener?: { beginContact(contact: Contact): void; endContact(contact: Contact): void; preSolve(contact: Contact, oldManifold: Manifold): void; }): void; solvePositionConstraint(step: TimeStep): number; solvePositionConstraintTOI(step: TimeStep, toiA: Body$1, toiB: Body$1): number; private _solvePositionConstraint; initVelocityConstraint(step: TimeStep): void; warmStartConstraint(step: TimeStep): void; storeConstraintImpulses(step: TimeStep): void; solveVelocityConstraint(step: TimeStep): void; } /** * A static body does not move under simulation and behaves as if it has infinite mass. * Internally, zero is stored for the mass and the inverse mass. * Static bodies can be moved manually by the user. * A static body has zero velocity. * Static bodies do not collide with other static or kinematic bodies. * * A kinematic body moves under simulation according to its velocity. * Kinematic bodies do not respond to forces. * They can be moved manually by the user, but normally a kinematic body is moved by setting its velocity. * A kinematic body behaves as if it has infinite mass, however, zero is stored for the mass and the inverse mass. * Kinematic bodies do not collide with other kinematic or static bodies. * * A dynamic body is fully simulated. * They can be moved manually by the user, but normally they move according to forces. * A dynamic body can collide with all body types. * A dynamic body always has finite, non-zero mass. * If you try to set the mass of a dynamic body to zero, it will automatically acquire a mass of one kilogram and it won't rotate. */ export type BodyType = "static" | "kinematic" | "dynamic"; export interface BodyDef { /** * Body types are static, kinematic, or dynamic. Note: if a dynamic * body would have zero mass, the mass is set to one. */ type?: BodyType; /** * The world position of the body. Avoid creating bodies at the * origin since this can lead to many overlapping shapes. */ position?: Vec2Value; /** * The world angle of the body in radians. */ angle?: number; /** * The linear velocity of the body's origin in world co-ordinates. */ linearVelocity?: Vec2Value; angularVelocity?: number; /** * Linear damping is use to reduce the linear velocity. The * damping parameter can be larger than 1.0 but the damping effect becomes * sensitive to the time step when the damping parameter is large. * Units are 1/time */ linearDamping?: number; /** * Angular damping is use to reduce the angular velocity. * The damping parameter can be larger than 1.0 but the damping effect * becomes sensitive to the time step when the damping parameter is large. * Units are 1/time */ angularDamping?: number; /** * Should this body be prevented from rotating? Useful for characters. */ fixedRotation?: boolean; /** * Is this a fast moving body that should be prevented from * tunneling through other moving bodies? Note that all bodies are * prevented from tunneling through kinematic and static bodies. This * setting is only considered on dynamic bodies. Warning: You should use * this flag sparingly since it increases processing time. */ bullet?: boolean; gravityScale?: number; /** * Set this flag to false if this body should never fall asleep. Note that this increases CPU usage. */ allowSleep?: boolean; /** * Is this body initially awake or sleeping? */ awake?: boolean; /** * Does this body start out active? */ active?: boolean; userData?: any; /** Styling for dev-tools. */ style?: Style; } /** * MassData This holds the mass data computed for a shape. */ export interface MassData { /** The mass of the shape, usually in kilograms. */ mass: number; /** The position of the shape's centroid relative to the shape's origin. */ center: Vec2Value; /** The rotational inertia of the shape about the local origin. */ I: number; } /** * A rigid body composed of one or more fixtures. * * To create a new Body use {@link World.createBody}. */ declare class Body$1 { /** @hidden */ static readonly STATIC: BodyType; /** @hidden */ static readonly KINEMATIC: BodyType; /** @hidden */ static readonly DYNAMIC: BodyType; /** Styling for dev-tools. */ style: Style; /** @hidden @experimental Similar to userData, but used by dev-tools or runtime environment. */ appData: Record<string, any>; isWorldLocked(): boolean; getWorld(): World; getNext(): Body$1 | null; setUserData(data: any): void; getUserData(): unknown; getFixtureList(): Fixture | null; getJointList(): JointEdge | null; /** * Warning: this list changes during the time step and you may miss some * collisions if you don't use ContactListener. */ getContactList(): ContactEdge | null; isStatic(): boolean; isDynamic(): boolean; isKinematic(): boolean; /** * This will alter the mass and velocity. */ setStatic(): Body$1; setDynamic(): Body$1; setKinematic(): Body$1; /** * Get the type of the body. */ getType(): BodyType; /** * Set the type of the body to "static", "kinematic" or "dynamic". * @param type The type of the body. * * Warning: This functio