New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@box2d/core

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@box2d/core - npm Package Compare versions

Comparing version 0.7.5 to 0.8.0

62

dist/collision/b2_broad_phase.d.ts
import { b2Vec2, XY } from "../common/b2_math";
import { b2AABB, b2RayCastInput } from "./b2_collision";
import { b2TreeNode, b2DynamicTree } from "./b2_dynamic_tree";
import { b2TreeNode } from "./b2_dynamic_tree";
/**
* The broad-phase is used for computing pairs and performing volume queries and ray casts.
* This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
* It is up to the client to consume the new pairs and to track subsequent overlap.
*/
export declare class b2BroadPhase<T> {
readonly m_tree: b2DynamicTree<T>;
private readonly m_tree;
private m_proxyCount;

@@ -12,19 +17,68 @@ private m_moveCount;

private m_queryProxy;
/**
* Create a proxy with an initial AABB. Pairs are not reported until
* UpdatePairs is called.
*/
CreateProxy(aabb: b2AABB, userData: T): b2TreeNode<T>;
/**
* Destroy a proxy. It is up to the client to remove any pairs.
*/
DestroyProxy(proxy: b2TreeNode<T>): 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(proxy: b2TreeNode<T>, aabb: b2AABB, displacement: b2Vec2): void;
/**
* Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
*/
TouchProxy(proxy: b2TreeNode<T>): void;
/**
* Get the number of proxies.
*/
GetProxyCount(): number;
/**
* Update the pairs. This results in pair callbacks. This can only add pairs.
*/
UpdatePairs(callback: (a: T, b: T) => void): void;
/**
* Query an AABB for overlapping proxies. The callback class
* is called for each proxy that overlaps the supplied AABB.
*/
Query(aabb: b2AABB, callback: (node: b2TreeNode<T>) => boolean): void;
QueryPoint(point: XY, callback: (node: b2TreeNode<T>) => boolean): void;
private QueryCallback;
/**
* 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 callback A callback class that is called for each proxy that is hit by the ray.
*/
RayCast(input: b2RayCastInput, callback: (input: b2RayCastInput, node: b2TreeNode<T>) => number): void;
/**
* Get the height of the embedded tree.
*/
GetTreeHeight(): number;
/**
* Get the balance of the embedded tree.
*/
GetTreeBalance(): number;
/**
* Get the quality metric of the embedded tree.
*/
GetTreeQuality(): number;
/**
* 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: XY): void;
BufferMove(proxy: b2TreeNode<T>): void;
UnBufferMove(proxy: b2TreeNode<T>): void;
private BufferMove;
private UnBufferMove;
}
//# sourceMappingURL=b2_broad_phase.d.ts.map

86

dist/collision/b2_broad_phase.js

@@ -23,5 +23,7 @@ "use strict";

const b2_dynamic_tree_1 = require("./b2_dynamic_tree");
/// The broad-phase is used for computing pairs and performing volume queries and ray casts.
/// This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
/// It is up to the client to consume the new pairs and to track subsequent overlap.
/**
* The broad-phase is used for computing pairs and performing volume queries and ray casts.
* This broad-phase does not persist pairs. Instead, this reports potentially new pairs.
* It is up to the client to consume the new pairs and to track subsequent overlap.
*/
class b2BroadPhase {

@@ -38,6 +40,6 @@ constructor() {

// A proxy cannot form a pair with itself.
if (proxy.m_id === this.m_queryProxy.m_id) {
if (proxy.id === this.m_queryProxy.id) {
return true;
}
if (proxy.moved && proxy.m_id > this.m_queryProxy.m_id) {
if (proxy.moved && proxy.id > this.m_queryProxy.id) {
// Both proxies are moving. Avoid duplicate pairs.

@@ -48,3 +50,3 @@ return true;

this.m_pairBuffer[this.m_pairCount] =
proxy.m_id < this.m_queryProxy.m_id ? [proxy, this.m_queryProxy] : [this.m_queryProxy, proxy];
proxy.id < this.m_queryProxy.id ? [proxy, this.m_queryProxy] : [this.m_queryProxy, proxy];
++this.m_pairCount;

@@ -54,4 +56,6 @@ return true;

}
/// Create a proxy with an initial AABB. Pairs are not reported until
/// UpdatePairs is called.
/**
* Create a proxy with an initial AABB. Pairs are not reported until
* UpdatePairs is called.
*/
CreateProxy(aabb, userData) {

@@ -63,3 +67,5 @@ const proxy = this.m_tree.CreateProxy(aabb, userData);

}
/// Destroy a proxy. It is up to the client to remove any pairs.
/**
* Destroy a proxy. It is up to the client to remove any pairs.
*/
DestroyProxy(proxy) {

@@ -70,4 +76,6 @@ this.UnBufferMove(proxy);

}
/// Call MoveProxy as many times as you like, then when you are done
/// call UpdatePairs to finalized the proxy pairs (for your time step).
/**
* 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(proxy, aabb, displacement) {

@@ -79,11 +87,17 @@ const buffer = this.m_tree.MoveProxy(proxy, aabb, displacement);

}
/// Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
/**
* Call to trigger a re-processing of it's pairs on the next call to UpdatePairs.
*/
TouchProxy(proxy) {
this.BufferMove(proxy);
}
/// Get the number of proxies.
/**
* Get the number of proxies.
*/
GetProxyCount() {
return this.m_proxyCount;
}
/// Update the pairs. This results in pair callbacks. This can only add pairs.
/**
* Update the pairs. This results in pair callbacks. This can only add pairs.
*/
UpdatePairs(callback) {

@@ -120,4 +134,6 @@ // Reset pair buffer

}
/// Query an AABB for overlapping proxies. The callback class
/// is called for each proxy that overlaps the supplied AABB.
/**
* Query an AABB for overlapping proxies. The callback class
* is called for each proxy that overlaps the supplied AABB.
*/
Query(aabb, callback) {

@@ -129,27 +145,39 @@ this.m_tree.Query(aabb, callback);

}
/// 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 callback a callback class that is called for each proxy that is hit by the ray.
/**
* 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 callback A callback class that is called for each proxy that is hit by the ray.
*/
RayCast(input, callback) {
this.m_tree.RayCast(input, callback);
}
/// Get the height of the embedded tree.
/**
* Get the height of the embedded tree.
*/
GetTreeHeight() {
return this.m_tree.GetHeight();
}
/// Get the balance of the embedded tree.
/**
* Get the balance of the embedded tree.
*/
GetTreeBalance() {
return this.m_tree.GetMaxBalance();
}
/// Get the quality metric of the embedded tree.
/**
* Get the quality metric of the embedded tree.
*/
GetTreeQuality() {
return this.m_tree.GetAreaRatio();
}
/// 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
/**
* 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) {

@@ -156,0 +184,0 @@ this.m_tree.ShiftOrigin(newOrigin);

@@ -6,2 +6,11 @@ import { b2Vec2, b2Transform, XY } from "../common/b2_math";

import { b2EdgeShape } from "./b2_edge_shape";
import { b2Color, b2Draw } from "../common/b2_draw";
/**
* A chain shape is a free form sequence of line segments.
* The chain has one-sided collision, with the surface normal pointing to the right of the edge.
* This provides a counter-clockwise winding like the polygon shape.
* Connectivity information is used to create smooth collisions.
*
* @warning the chain will not collide properly if there are self-intersections.
*/
export declare class b2ChainShape extends b2Shape {

@@ -12,16 +21,41 @@ m_vertices: b2Vec2[];

constructor();
CreateLoop(vertices: XY[]): b2ChainShape;
CreateLoop(vertices: XY[], count: number): b2ChainShape;
CreateLoop(vertices: number[]): b2ChainShape;
private CreateLoopEx;
CreateChain(vertices: XY[], prevVertex: Readonly<XY>, nextVertex: Readonly<XY>): b2ChainShape;
/**
* Create a loop. This automatically adjusts connectivity.
*
* @param vertices An array of vertices, these are copied
* @param count The vertex count
*/
CreateLoop(vertices: XY[], count?: number): b2ChainShape;
/**
* Create a chain with ghost vertices to connect multiple chains together.
*
* @param vertices An array of vertices, these are copied
* @param count The vertex count
* @param prevVertex Previous vertex from chain that connects to the start
* @param nextVertex Next vertex from chain that connects to the end
*/
CreateChain(vertices: XY[], count: number, prevVertex: Readonly<XY>, nextVertex: Readonly<XY>): b2ChainShape;
CreateChain(vertices: number[], prevVertex: Readonly<XY>, nextVertex: Readonly<XY>): b2ChainShape;
private CreateChainEx;
/**
* Implement b2Shape. Vertices are cloned using b2Alloc.
*/
Clone(): b2ChainShape;
Copy(other: b2ChainShape): b2ChainShape;
/**
* @see b2Shape::GetChildCount
*/
GetChildCount(): number;
/**
* Get a child edge.
*/
GetChildEdge(edge: b2EdgeShape, index: number): void;
/**
* This always return false.
*
* @see b2Shape::TestPoint
*/
TestPoint(_xf: b2Transform, _p: XY): boolean;
private static RayCast_s_edgeShape;
/**
* Implement b2Shape.
*/
RayCast(output: b2RayCastOutput, input: b2RayCastInput, xf: b2Transform, childIndex: number): boolean;

@@ -32,6 +66,15 @@ private static ComputeAABB_s_v1;

private static ComputeAABB_s_upper;
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb: b2AABB, xf: b2Transform, childIndex: number): void;
/**
* Chains have zero mass.
*
* @see b2Shape::ComputeMass
*/
ComputeMass(massData: b2MassData, _density: number): void;
SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void;
Draw(draw: b2Draw, color: b2Color): void;
}
//# sourceMappingURL=b2_chain_shape.d.ts.map

@@ -26,7 +26,10 @@ "use strict";

const b2_edge_shape_1 = require("./b2_edge_shape");
/// A chain shape is a free form sequence of line segments.
/// The chain has one-sided collision, with the surface normal pointing to the right of the edge.
/// This provides a counter-clockwise winding like the polygon shape.
/// Connectivity information is used to create smooth collisions.
/// @warning the chain will not collide properly if there are self-intersections.
/**
* A chain shape is a free form sequence of line segments.
* The chain has one-sided collision, with the surface normal pointing to the right of the edge.
* This provides a counter-clockwise winding like the polygon shape.
* Connectivity information is used to create smooth collisions.
*
* @warning the chain will not collide properly if there are self-intersections.
*/
class b2ChainShape extends b2_shape_1.b2Shape {

@@ -39,13 +42,9 @@ constructor() {

}
CreateLoop(...args) {
if (typeof args[0][0] === "number") {
const vertices = args[0];
b2_common_1.b2Assert(vertices.length % 2 === 0);
return this.CreateLoopEx((index) => ({ x: vertices[index * 2], y: vertices[index * 2 + 1] }), vertices.length / 2);
}
const vertices = args[0];
const count = args[1] || vertices.length;
return this.CreateLoopEx((index) => vertices[index], count);
}
CreateLoopEx(vertices, count) {
/**
* Create a loop. This automatically adjusts connectivity.
*
* @param vertices An array of vertices, these are copied
* @param count The vertex count
*/
CreateLoop(vertices, count = vertices.length) {
// DEBUG: b2Assert(count >= 3);

@@ -56,4 +55,4 @@ if (count < 3) {

// DEBUG: for (let i = 1; i < count; ++i) {
// DEBUG: const v1 = vertices[start + i - 1];
// DEBUG: const v2 = vertices[start + i];
// DEBUG: const v1 = vertices[i - 1];
// DEBUG: const v2 = vertices[i];
// DEBUG: // If the code crashes here, it means your vertices are too close together.

@@ -64,3 +63,3 @@ // DEBUG: b2Assert(b2Vec2.DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop);

for (let i = 0; i < count; ++i) {
const { x, y } = vertices(i);
const { x, y } = vertices[i];
this.m_vertices[i] = new b2_math_1.b2Vec2(x, y);

@@ -73,27 +72,19 @@ }

}
CreateChain(...args) {
if (typeof args[0][0] === "number") {
const vertices = args[0];
const prevVertex = args[1];
const nextVertex = args[2];
b2_common_1.b2Assert(vertices.length % 2 === 0);
return this.CreateChainEx((index) => ({ x: vertices[index * 2], y: vertices[index * 2 + 1] }), vertices.length / 2, prevVertex, nextVertex);
}
const vertices = args[0];
const count = args[1] || vertices.length;
const prevVertex = args[2];
const nextVertex = args[3];
return this.CreateChainEx((index) => vertices[index], count, prevVertex, nextVertex);
}
CreateChainEx(vertices, count, prevVertex, nextVertex) {
/**
* Create a chain with ghost vertices to connect multiple chains together.
*
* @param vertices An array of vertices, these are copied
* @param count The vertex count
* @param prevVertex Previous vertex from chain that connects to the start
* @param nextVertex Next vertex from chain that connects to the end
*/
CreateChain(vertices, count, prevVertex, nextVertex) {
// DEBUG: b2Assert(count >= 2);
// DEBUG: for (let i = 1; i < count; ++i) {
// DEBUG: const v1 = vertices[start + i - 1];
// DEBUG: const v2 = vertices[start + i];
// DEBUG: // If the code crashes here, it means your vertices are too close together.
// DEBUG: b2Assert(b2Vec2.DistanceSquared(v1, v2) > b2_linearSlop * b2_linearSlop);
// DEBUG: b2Assert(b2Vec2.DistanceSquared(vertices[i-1], vertices[i]) > b2_linearSlop * b2_linearSlop);
// DEBUG: }
this.m_vertices.length = count;
for (let i = 0; i < count; ++i) {
const { x, y } = vertices(i);
const { x, y } = vertices[i];
this.m_vertices[i] = new b2_math_1.b2Vec2(x, y);

@@ -105,3 +96,5 @@ }

}
/// Implement b2Shape. Vertices are cloned using b2Alloc.
/**
* Implement b2Shape. Vertices are cloned using b2Alloc.
*/
Clone() {

@@ -113,5 +106,7 @@ return new b2ChainShape().Copy(this);

// DEBUG: b2Assert(other instanceof b2ChainShape);
return this.CreateChainEx((index) => other.m_vertices[index], other.m_vertices.length, other.m_prevVertex, other.m_nextVertex);
return this.CreateChain(other.m_vertices, other.m_vertices.length, other.m_prevVertex, other.m_nextVertex);
}
/// @see b2Shape::GetChildCount
/**
* @see b2Shape::GetChildCount
*/
GetChildCount() {

@@ -121,3 +116,5 @@ // edge count = vertex count - 1

}
/// Get a child edge.
/**
* Get a child edge.
*/
GetChildEdge(edge, index) {

@@ -142,20 +139,37 @@ // DEBUG: b2Assert(0 <= index && index < this.m_vertices.length - 1);

}
/// This always return false.
/// @see b2Shape::TestPoint
/**
* This always return false.
*
* @see b2Shape::TestPoint
*/
TestPoint(_xf, _p) {
return false;
}
/**
* Implement b2Shape.
*/
RayCast(output, input, xf, childIndex) {
// DEBUG: b2Assert(childIndex < this.m_vertices.length);
const edgeShape = b2ChainShape.RayCast_s_edgeShape;
edgeShape.m_vertex1.Copy(this.m_vertices[childIndex]);
edgeShape.m_vertex2.Copy(this.m_vertices[(childIndex + 1) % this.m_vertices.length]);
const i1 = childIndex;
let i2 = childIndex + 1;
if (i2 === this.m_vertices.length) {
i2 = 0;
}
edgeShape.m_vertex1.Copy(this.m_vertices[i1]);
edgeShape.m_vertex2.Copy(this.m_vertices[i2]);
return edgeShape.RayCast(output, input, xf, 0);
}
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb, xf, childIndex) {
// DEBUG: b2Assert(childIndex < this.m_vertices.length);
const vertexi1 = this.m_vertices[childIndex];
const vertexi2 = this.m_vertices[(childIndex + 1) % this.m_vertices.length];
const v1 = b2_math_1.b2Transform.MultiplyVec2(xf, vertexi1, b2ChainShape.ComputeAABB_s_v1);
const v2 = b2_math_1.b2Transform.MultiplyVec2(xf, vertexi2, b2ChainShape.ComputeAABB_s_v2);
const i1 = childIndex;
let i2 = childIndex + 1;
if (i2 === this.m_vertices.length) {
i2 = 0;
}
const v1 = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertices[i1], b2ChainShape.ComputeAABB_s_v1);
const v2 = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertices[i2], b2ChainShape.ComputeAABB_s_v2);
const lower = b2_math_1.b2Vec2.Min(v1, v2, b2ChainShape.ComputeAABB_s_lower);

@@ -168,4 +182,7 @@ const upper = b2_math_1.b2Vec2.Max(v1, v2, b2ChainShape.ComputeAABB_s_upper);

}
/// Chains have zero mass.
/// @see b2Shape::ComputeMass
/**
* Chains have zero mass.
*
* @see b2Shape::ComputeMass
*/
ComputeMass(massData, _density) {

@@ -189,7 +206,14 @@ massData.mass = 0;

}
Draw(draw, color) {
const vertices = this.m_vertices;
let v1 = vertices[0];
for (let i = 1; i < vertices.length; ++i) {
const v2 = vertices[i];
draw.DrawSegment(v1, v2, color);
v1 = v2;
}
}
}
exports.b2ChainShape = b2ChainShape;
/// Implement b2Shape.
b2ChainShape.RayCast_s_edgeShape = new b2_edge_shape_1.b2EdgeShape();
/// @see b2Shape::ComputeAABB
b2ChainShape.ComputeAABB_s_v1 = new b2_math_1.b2Vec2();

@@ -196,0 +220,0 @@ b2ChainShape.ComputeAABB_s_v2 = new b2_math_1.b2Vec2();

@@ -0,1 +1,2 @@

import { b2Color, b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Transform, XY } from "../common/b2_math";

@@ -5,11 +6,24 @@ import { b2AABB, b2RayCastInput, b2RayCastOutput } from "./b2_collision";

import { b2MassData, b2Shape } from "./b2_shape";
/**
* A solid circle shape
*/
export declare class b2CircleShape extends b2Shape {
/** Position */
readonly m_p: b2Vec2;
constructor(radius?: number);
Set(position: XY, radius?: number): this;
/**
* Implement b2Shape.
*/
Clone(): b2CircleShape;
Copy(other: b2CircleShape): b2CircleShape;
/**
* @see b2Shape::GetChildCount
*/
GetChildCount(): number;
private static TestPoint_s_center;
private static TestPoint_s_d;
/**
* Implement b2Shape.
*/
TestPoint(transform: b2Transform, p: XY): boolean;

@@ -19,8 +33,24 @@ private static RayCast_s_position;

private static RayCast_s_r;
/**
* Implement b2Shape.
*
* @note because the circle is solid, rays that start inside do not hit because the normal is
* not defined. Collision Detection in Interactive 3D Environments by Gino van den Bergen
* From Section 3.1.2
* x = s + a * r
* norm(x) = radius
*/
RayCast(output: b2RayCastOutput, input: b2RayCastInput, transform: b2Transform, _childIndex: number): boolean;
private static ComputeAABB_s_p;
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb: b2AABB, transform: b2Transform, _childIndex: number): void;
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData: b2MassData, density: number): void;
SetupDistanceProxy(proxy: b2DistanceProxy, _index: number): void;
Draw(draw: b2Draw, color: b2Color): void;
}
//# sourceMappingURL=b2_circle_shape.d.ts.map

@@ -25,6 +25,9 @@ "use strict";

const b2_shape_1 = require("./b2_shape");
/// A solid circle shape
/**
* A solid circle shape
*/
class b2CircleShape extends b2_shape_1.b2Shape {
constructor(radius = 0) {
super(b2_shape_1.b2ShapeType.e_circle, radius);
/** Position */
this.m_p = new b2_math_1.b2Vec2();

@@ -37,3 +40,5 @@ }

}
/// Implement b2Shape.
/**
* Implement b2Shape.
*/
Clone() {

@@ -48,6 +53,11 @@ return new b2CircleShape().Copy(this);

}
/// @see b2Shape::GetChildCount
/**
* @see b2Shape::GetChildCount
*/
GetChildCount() {
return 1;
}
/**
* Implement b2Shape.
*/
TestPoint(transform, p) {

@@ -58,2 +68,11 @@ const center = b2_math_1.b2Transform.MultiplyVec2(transform, this.m_p, b2CircleShape.TestPoint_s_center);

}
/**
* Implement b2Shape.
*
* @note because the circle is solid, rays that start inside do not hit because the normal is
* not defined. Collision Detection in Interactive 3D Environments by Gino van den Bergen
* From Section 3.1.2
* x = s + a * r
* norm(x) = radius
*/
RayCast(output, input, transform, _childIndex) {

@@ -83,2 +102,5 @@ const position = b2_math_1.b2Transform.MultiplyVec2(transform, this.m_p, b2CircleShape.RayCast_s_position);

}
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb, transform, _childIndex) {

@@ -89,3 +111,5 @@ const p = b2_math_1.b2Transform.MultiplyVec2(transform, this.m_p, b2CircleShape.ComputeAABB_s_p);

}
/// @see b2Shape::ComputeMass
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData, density) {

@@ -104,18 +128,15 @@ const radius_sq = this.m_radius ** 2;

}
Draw(draw, color) {
const center = this.m_p;
const radius = this.m_radius;
const axis = b2_math_1.b2Vec2.UNITX;
draw.DrawSolidCircle(center, radius, axis, color);
}
}
exports.b2CircleShape = b2CircleShape;
/// Implement b2Shape.
b2CircleShape.TestPoint_s_center = new b2_math_1.b2Vec2();
b2CircleShape.TestPoint_s_d = new b2_math_1.b2Vec2();
/// Implement b2Shape.
/// @note because the circle is solid, rays that start inside do not hit because the normal is
/// not defined.
// Collision Detection in Interactive 3D Environments by Gino van den Bergen
// From Section 3.1.2
// x = s + a * r
// norm(x) = radius
b2CircleShape.RayCast_s_position = new b2_math_1.b2Vec2();
b2CircleShape.RayCast_s_s = new b2_math_1.b2Vec2();
b2CircleShape.RayCast_s_r = new b2_math_1.b2Vec2();
/// @see b2Shape::ComputeAABB
b2CircleShape.ComputeAABB_s_p = new b2_math_1.b2Vec2();

@@ -0,0 +0,0 @@ import { b2Transform } from "../common/b2_math";

@@ -54,3 +54,3 @@ "use strict";

const vertIndex1 = normalIndex;
const vertIndex2 = (vertIndex1 + 1) % vertexCount;
const vertIndex2 = vertIndex1 + 1 < vertexCount ? vertIndex1 + 1 : 0;
const v1 = vertices[vertIndex1];

@@ -57,0 +57,0 @@ const v2 = vertices[vertIndex2];

@@ -0,0 +0,0 @@ import { b2Transform } from "../common/b2_math";

@@ -8,2 +8,3 @@ "use strict";

const b2_collision_1 = require("./b2_collision");
const b2_settings_1 = require("../common/b2_settings");
const b2CollideEdgeAndCircle_s_Q = new b2_math_1.b2Vec2();

@@ -25,9 +26,6 @@ const b2CollideEdgeAndCircle_s_e = new b2_math_1.b2Vec2();

// Normal points to the right for a CCW winding
// b2Vec2 n(e.y, -e.x);
// const n = b2CollideEdgeAndCircle_s_n.Set(-e.y, e.x);
const n = b2CollideEdgeAndCircle_s_n.Set(e.y, -e.x);
// float offset = b2Dot(n, Q - A);
const offset = b2_math_1.b2Vec2.Dot(n, b2_math_1.b2Vec2.Subtract(Q, A, b2_math_1.b2Vec2.s_t0));
const oneSided = edgeA.m_oneSided;
if (oneSided && offset < 0.0) {
if (oneSided && offset < 0) {
return;

@@ -39,3 +37,2 @@ }

const radius = edgeA.m_radius + circleB.m_radius;
// const cf = new b2ContactFeature();
const id = b2CollideEdgeAndCircle_s_id;

@@ -70,4 +67,2 @@ id.cf.indexB = 0;

manifold.points[0].id.Copy(id);
// manifold.points[0].id.key = 0;
// manifold.points[0].id.cf = cf;
manifold.points[0].localPoint.Copy(circleB.m_p);

@@ -102,4 +97,2 @@ return;

manifold.points[0].id.Copy(id);
// manifold.points[0].id.key = 0;
// manifold.points[0].id.cf = cf;
manifold.points[0].localPoint.Copy(circleB.m_p);

@@ -130,4 +123,2 @@ return;

manifold.points[0].id.Copy(id);
// manifold.points[0].id.key = 0;
// manifold.points[0].id.cf = cf;
manifold.points[0].localPoint.Copy(circleB.m_p);

@@ -142,2 +133,3 @@ }

})(b2EPAxisType || (b2EPAxisType = {}));
// This structure is used to keep track of the best separating axis.
class b2EPAxis {

@@ -151,9 +143,11 @@ constructor() {

}
// This holds polygon B expressed in frame A.
class b2TempPolygon {
constructor() {
this.vertices = [];
this.normals = [];
this.vertices = b2_common_1.b2MakeArray(b2_settings_1.b2_maxPolygonVertices, b2_math_1.b2Vec2);
this.normals = b2_common_1.b2MakeArray(b2_settings_1.b2_maxPolygonVertices, b2_math_1.b2Vec2);
this.count = 0;
}
}
// Reference face used for clipping
class b2ReferenceFace {

@@ -176,18 +170,15 @@ constructor() {

function b2ComputeEdgeSeparation(polygonB, v1, normal1) {
// b2EPAxis axis;
const axis = b2ComputeEdgeSeparation_s_axis;
axis.type = b2EPAxisType.e_edgeA;
axis.index = -1;
axis.separation = -Number.MAX_VALUE; // -FLT_MAX;
axis.separation = -b2_common_1.b2_maxFloat;
axis.normal.SetZero();
// b2Vec2 axes[2] = { normal1, -normal1 };
const axes = b2ComputeEdgeSeparation_s_axes;
axes[0].Copy(normal1);
axes[1].Copy(normal1).Negate();
b2_math_1.b2Vec2.Negate(normal1, axes[1]);
// Find axis with least overlap (min-max problem)
for (let j = 0; j < 2; ++j) {
let sj = Number.MAX_VALUE; // FLT_MAX;
let sj = b2_common_1.b2_maxFloat;
// Find deepest polygon vertex along axis j
for (let i = 0; i < polygonB.count; ++i) {
// float si = b2Dot(axes[j], polygonB.vertices[i] - v1);
const si = b2_math_1.b2Vec2.Dot(axes[j], b2_math_1.b2Vec2.Subtract(polygonB.vertices[i], v1, b2_math_1.b2Vec2.s_t0));

@@ -213,12 +204,8 @@ if (si < sj) {

axis.index = -1;
axis.separation = -Number.MAX_VALUE; // -FLT_MAX;
axis.separation = -b2_common_1.b2_maxFloat;
axis.normal.SetZero();
for (let i = 0; i < polygonB.count; ++i) {
// b2Vec2 n = -polygonB.normals[i];
const n = b2_math_1.b2Vec2.Negate(polygonB.normals[i], b2ComputePolygonSeparation_s_n);
// float s1 = b2Dot(n, polygonB.vertices[i] - v1);
const s1 = b2_math_1.b2Vec2.Dot(n, b2_math_1.b2Vec2.Subtract(polygonB.vertices[i], v1, b2_math_1.b2Vec2.s_t0));
// float s2 = b2Dot(n, polygonB.vertices[i] - v2);
const s2 = b2_math_1.b2Vec2.Dot(n, b2_math_1.b2Vec2.Subtract(polygonB.vertices[i], v2, b2_math_1.b2Vec2.s_t0));
// float s = Math.min(s1, s2);
const s = Math.min(s1, s2);

@@ -249,40 +236,23 @@ if (s > axis.separation) {

manifold.pointCount = 0;
// b2Transform xf = b2MulT(xfA, xfB);
const xf = b2_math_1.b2Transform.TransposeMultiply(xfA, xfB, b2CollideEdgeAndPolygon_s_xf);
// b2Vec2 centroidB = b2Mul(xf, polygonB.m_centroid);
const centroidB = b2_math_1.b2Transform.MultiplyVec2(xf, polygonB.m_centroid, b2CollideEdgeAndPolygon_s_centroidB);
// b2Vec2 v1 = edgeA.m_vertex1;
const v1 = edgeA.m_vertex1;
// b2Vec2 v2 = edgeA.m_vertex2;
const v2 = edgeA.m_vertex2;
// b2Vec2 edge1 = v2 - v1;
const edge1 = b2_math_1.b2Vec2.Subtract(v2, v1, b2CollideEdgeAndPolygon_s_edge1);
edge1.Normalize();
// Normal points to the right for a CCW winding
// b2Vec2 normal1(edge1.y, -edge1.x);
const normal1 = b2CollideEdgeAndPolygon_s_normal1.Set(edge1.y, -edge1.x);
// float offset1 = b2Dot(normal1, centroidB - v1);
const offset1 = b2_math_1.b2Vec2.Dot(normal1, b2_math_1.b2Vec2.Subtract(centroidB, v1, b2_math_1.b2Vec2.s_t0));
const oneSided = edgeA.m_oneSided;
if (oneSided && offset1 < 0.0) {
if (oneSided && offset1 < 0) {
return;
}
// Get polygonB in frameA
// b2TempPolygon tempPolygonB;
const tempPolygonB = b2CollideEdgeAndPolygon_s_tempPolygonB;
tempPolygonB.count = polygonB.m_count;
for (let i = 0; i < polygonB.m_count; ++i) {
if (tempPolygonB.vertices.length <= i) {
tempPolygonB.vertices.push(new b2_math_1.b2Vec2());
}
if (tempPolygonB.normals.length <= i) {
tempPolygonB.normals.push(new b2_math_1.b2Vec2());
}
// tempPolygonB.vertices[i] = b2Mul(xf, polygonB.m_vertices[i]);
b2_math_1.b2Transform.MultiplyVec2(xf, polygonB.m_vertices[i], tempPolygonB.vertices[i]);
// tempPolygonB.normals[i] = b2Mul(xf.q, polygonB.m_normals[i]);
b2_math_1.b2Rot.MultiplyVec2(xf.q, polygonB.m_normals[i], tempPolygonB.normals[i]);
}
const radius = polygonB.m_radius + edgeA.m_radius;
// b2EPAxis edgeAxis = b2ComputeEdgeSeparation(tempPolygonB, v1, normal1);
const edgeAxis = b2ComputeEdgeSeparation(tempPolygonB, v1, normal1);

@@ -292,3 +262,2 @@ if (edgeAxis.separation > radius) {

}
// b2EPAxis polygonAxis = b2ComputePolygonSeparation(tedge0.y, -edge0.xempPolygonB, v1, v2);
const polygonAxis = b2ComputePolygonSeparation(tempPolygonB, v1, v2);

@@ -312,16 +281,12 @@ if (polygonAxis.separation > radius) {

// See https://box2d.org/posts/2020/06/ghost-collisions/
// b2Vec2 edge0 = v1 - edgeA.m_vertex0;
const edge0 = b2_math_1.b2Vec2.Subtract(v1, edgeA.m_vertex0, b2CollideEdgeAndPolygon_s_edge0);
edge0.Normalize();
// b2Vec2 normal0(edge0.y, -edge0.x);
const normal0 = b2CollideEdgeAndPolygon_s_normal0.Set(edge0.y, -edge0.x);
const convex1 = b2_math_1.b2Vec2.Cross(edge0, edge1) >= 0.0;
// b2Vec2 edge2 = edgeA.m_vertex3 - v2;
const convex1 = b2_math_1.b2Vec2.Cross(edge0, edge1) >= 0;
const edge2 = b2_math_1.b2Vec2.Subtract(edgeA.m_vertex3, v2, b2CollideEdgeAndPolygon_s_edge2);
edge2.Normalize();
// b2Vec2 normal2(edge2.y, -edge2.x);
const normal2 = b2CollideEdgeAndPolygon_s_normal2.Set(edge2.y, -edge2.x);
const convex2 = b2_math_1.b2Vec2.Cross(edge1, edge2) >= 0.0;
const convex2 = b2_math_1.b2Vec2.Cross(edge1, edge2) >= 0;
const sinTol = 0.1;
const side1 = b2_math_1.b2Vec2.Dot(primaryAxis.normal, edge1) <= 0.0;
const side1 = b2_math_1.b2Vec2.Dot(primaryAxis.normal, edge1) <= 0;
// Check Gauss Map

@@ -353,5 +318,3 @@ if (side1) {

}
// b2ClipVertex clipPoints[2];
const clipPoints = b2CollideEdgeAndPolygon_s_clipPoints;
// b2ReferenceFace ref;
const ref = b2CollideEdgeAndPolygon_s_ref;

@@ -387,3 +350,3 @@ if (primaryAxis.type === b2EPAxisType.e_edgeA) {

ref.normal.Copy(primaryAxis.normal);
ref.sideNormal1.Copy(edge1).Negate(); // ref.sideNormal1 = -edge1;
b2_math_1.b2Vec2.Negate(edge1, ref.sideNormal1);
ref.sideNormal2.Copy(edge1);

@@ -410,3 +373,3 @@ }

ref.sideNormal1.Set(ref.normal.y, -ref.normal.x);
ref.sideNormal2.Copy(ref.sideNormal1).Negate(); // ref.sideNormal2 = -ref.sideNormal1;
b2_math_1.b2Vec2.Negate(ref.sideNormal1, ref.sideNormal2);
}

@@ -416,7 +379,4 @@ ref.sideOffset1 = b2_math_1.b2Vec2.Dot(ref.sideNormal1, ref.v1);

// Clip incident edge against reference face side planes
// b2ClipVertex clipPoints1[2];
const clipPoints1 = b2CollideEdgeAndPolygon_s_clipPoints1; // [new b2ClipVertex(), new b2ClipVertex()];
// b2ClipVertex clipPoints2[2];
const clipPoints2 = b2CollideEdgeAndPolygon_s_clipPoints2; // [new b2ClipVertex(), new b2ClipVertex()];
// int32 np;
const clipPoints1 = b2CollideEdgeAndPolygon_s_clipPoints1;
const clipPoints2 = b2CollideEdgeAndPolygon_s_clipPoints2;
let np;

@@ -448,3 +408,3 @@ // Clip to side 1

if (primaryAxis.type === b2EPAxisType.e_edgeA) {
b2_math_1.b2Transform.TransposeMultiplyVec2(xf, clipPoints2[i].v, cp.localPoint); // cp.localPoint = b2MulT(xf, clipPoints2[i].v);
b2_math_1.b2Transform.TransposeMultiplyVec2(xf, clipPoints2[i].v, cp.localPoint);
cp.id.Copy(clipPoints2[i].id);

@@ -451,0 +411,0 @@ }

@@ -0,0 +0,0 @@ import { b2Transform } from "../common/b2_math";

@@ -142,12 +142,12 @@ "use strict";

const iv2 = edge1 + 1 < count1 ? edge1 + 1 : 0;
const local_v11 = vertices1[iv1];
const local_v12 = vertices1[iv2];
const localTangent = b2_math_1.b2Vec2.Subtract(local_v12, local_v11, b2CollidePolygons_s_localTangent);
let v11 = vertices1[iv1];
let v12 = vertices1[iv2];
const localTangent = b2_math_1.b2Vec2.Subtract(v12, v11, b2CollidePolygons_s_localTangent);
localTangent.Normalize();
const localNormal = b2_math_1.b2Vec2.CrossVec2One(localTangent, b2CollidePolygons_s_localNormal);
const planePoint = b2_math_1.b2Vec2.Mid(local_v11, local_v12, b2CollidePolygons_s_planePoint);
const planePoint = b2_math_1.b2Vec2.Mid(v11, v12, b2CollidePolygons_s_planePoint);
const tangent = b2_math_1.b2Rot.MultiplyVec2(xf1.q, localTangent, b2CollidePolygons_s_tangent);
const normal = b2_math_1.b2Vec2.CrossVec2One(tangent, b2CollidePolygons_s_normal);
const v11 = b2_math_1.b2Transform.MultiplyVec2(xf1, local_v11, b2CollidePolygons_s_v11);
const v12 = b2_math_1.b2Transform.MultiplyVec2(xf1, local_v12, b2CollidePolygons_s_v12);
v11 = b2_math_1.b2Transform.MultiplyVec2(xf1, v11, b2CollidePolygons_s_v11);
v12 = b2_math_1.b2Transform.MultiplyVec2(xf1, v12, b2CollidePolygons_s_v12);
// Face offset.

@@ -154,0 +154,0 @@ const frontOffset = b2_math_1.b2Vec2.Dot(normal, v11);

import { b2Vec2, b2Transform, XY } from "../common/b2_math";
import type { b2Shape } from "./b2_shape";
/**
* @file
* Structures and functions used for computing contact points, distance
* queries, and TOI queries.
*/
export declare enum b2ContactFeatureType {

@@ -7,8 +12,16 @@ e_vertex = 0,

}
/**
* The features that intersect to form the contact point
* This must be 4 bytes or less.
*/
export declare class b2ContactFeature {
private m_key;
private m_key_invalid;
/** Feature index on shapeA */
private m_indexA;
/** Feature index on shapeB */
private m_indexB;
/** The feature type on shapeA */
private m_typeA;
/** The feature type on shapeB */
private m_typeB;

@@ -26,2 +39,5 @@ get key(): number;

}
/**
* Contact ids to facilitate warm starting.
*/
export declare class b2ContactID {

@@ -34,8 +50,23 @@ readonly cf: b2ContactFeature;

}
/**
* 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.
* The local point usage depends on the manifold type:
* -e_circles: the local center of circleB
* -e_faceA: the local center of cirlceB or the clip point of polygonB
* -e_faceB: the clip point of polygonA
* This structure is stored across time steps, so we keep it small.
* Note: the impulses are used for internal caching and may not
* provide reliable contact forces, especially for high speed collisions.
*/
export declare class b2ManifoldPoint {
/** Usage depends on manifold type */
readonly localPoint: b2Vec2;
/** The non-penetration impulse */
normalImpulse: number;
/** The friction impulse */
tangentImpulse: number;
/** Uniquely identifies a contact point between two shapes */
readonly id: b2ContactID;
static MakeArray(length: number): b2ManifoldPoint[];
Reset(): void;

@@ -49,7 +80,29 @@ Copy(o: b2ManifoldPoint): b2ManifoldPoint;

}
/**
* A manifold for two touching convex shapes.
* Box2D supports multiple types of contact:
* - clip point versus plane with radius
* - point versus point with radius (circles)
* The local point usage depends on the manifold type:
* -e_circles: the local center of circleA
* -e_faceA: the center of faceA
* -e_faceB: the center of faceB
* Similarly the local normal usage:
* -e_circles: not used
* -e_faceA: the normal on polygonA
* -e_faceB: the normal on polygonB
* 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 b2Manifold {
/** The points of contact */
readonly points: b2ManifoldPoint[];
/** Not use for Type::e_points */
readonly localNormal: b2Vec2;
/** Usage depends on manifold type */
readonly localPoint: b2Vec2;
type: b2ManifoldType;
/** The number of manifold points */
pointCount: number;

@@ -60,5 +113,11 @@ Reset(): void;

}
/**
* This is used to compute the current state of a contact manifold.
*/
export declare class b2WorldManifold {
/** World vector pointing from A to B */
readonly normal: b2Vec2;
/** World contact point (point of intersection) */
readonly points: b2Vec2[];
/** A negative value indicates overlap, in meters */
readonly separations: number[];

@@ -73,15 +132,31 @@ private static Initialize_s_pointA;

}
/**
* This is used for determining the state of contact points.
*/
export declare enum b2PointState {
/** Point does not exist */
b2_nullState = 0,
/** Point was added in the update */
b2_addState = 1,
/** Point persisted across the update */
b2_persistState = 2,
/** Point was removed in the update */
b2_removeState = 3
}
/**
* 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 b2GetPointStates(state1: b2PointState[], state2: b2PointState[], manifold1: b2Manifold, manifold2: b2Manifold): void;
/**
* Used for computing contact manifolds.
*/
export declare class b2ClipVertex {
readonly v: b2Vec2;
readonly id: b2ContactID;
static MakeArray(length: number): b2ClipVertex[];
Copy(other: b2ClipVertex): b2ClipVertex;
}
/**
* Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
*/
export declare class b2RayCastInput {

@@ -93,2 +168,6 @@ readonly p1: b2Vec2;

}
/**
* Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
* come from b2RayCastInput.
*/
export declare class b2RayCastOutput {

@@ -99,13 +178,39 @@ readonly normal: b2Vec2;

}
/**
* An axis aligned bounding box.
*/
export declare class b2AABB {
/** The lower vertex */
readonly lowerBound: b2Vec2;
/** The upper vertex */
readonly upperBound: b2Vec2;
Copy(o: b2AABB): b2AABB;
/**
* Verify that the bounds are sorted.
*/
IsValid(): boolean;
/**
* Get the center of the AABB.
*/
GetCenter(out: XY): XY;
/**
* Get the extents of the AABB (half-widths).
*/
GetExtents(out: XY): XY;
/**
* Get the perimeter length
*/
GetPerimeter(): number;
/**
* Combine an AABB into this one.
*/
Combine1(aabb: b2AABB): b2AABB;
/**
* Combine two AABBs into this one.
*/
Combine2(aabb1: b2AABB, aabb2: b2AABB): b2AABB;
static Combine(aabb1: b2AABB, aabb2: b2AABB, out: b2AABB): b2AABB;
/**
* Does this aabb contain the provided AABB.
*/
Contains(aabb: b2AABB): boolean;

@@ -116,4 +221,10 @@ RayCast(output: b2RayCastOutput, input: b2RayCastInput): boolean;

}
/**
* Clipping for contact manifolds.
*/
export declare function b2ClipSegmentToLine(vOut: readonly [b2ClipVertex, b2ClipVertex], [vIn0, vIn1]: readonly [b2ClipVertex, b2ClipVertex], normal: b2Vec2, offset: number, vertexIndexA: number): number;
export declare function b2TestOverlapShape(shapeA: b2Shape, indexA: number, shapeB: b2Shape, indexB: number, xfA: b2Transform, xfB: b2Transform): boolean;
/**
* Determine if two generic shapes overlap.
*/
export declare function b2TestOverlap(shapeA: b2Shape, indexA: number, shapeB: b2Shape, indexB: number, xfA: b2Transform, xfB: b2Transform): boolean;
//# sourceMappingURL=b2_collision.d.ts.map

@@ -20,3 +20,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2TestOverlapShape = exports.b2ClipSegmentToLine = exports.b2AABB = exports.b2RayCastOutput = exports.b2RayCastInput = exports.b2ClipVertex = exports.b2GetPointStates = exports.b2PointState = exports.b2WorldManifold = exports.b2Manifold = exports.b2ManifoldType = exports.b2ManifoldPoint = exports.b2ContactID = exports.b2ContactFeature = exports.b2ContactFeatureType = void 0;
exports.b2TestOverlap = exports.b2ClipSegmentToLine = exports.b2AABB = exports.b2RayCastOutput = exports.b2RayCastInput = exports.b2ClipVertex = exports.b2GetPointStates = exports.b2PointState = exports.b2WorldManifold = exports.b2Manifold = exports.b2ManifoldType = exports.b2ManifoldPoint = exports.b2ContactID = exports.b2ContactFeature = exports.b2ContactFeatureType = void 0;
// DEBUG: import { b2Assert } from "../common/b2_common";

@@ -26,5 +26,7 @@ const b2_common_1 = require("../common/b2_common");

const b2_distance_1 = require("./b2_distance");
/// @file
/// Structures and functions used for computing contact points, distance
/// queries, and TOI queries.
/**
* @file
* Structures and functions used for computing contact points, distance
* queries, and TOI queries.
*/
var b2ContactFeatureType;

@@ -35,4 +37,6 @@ (function (b2ContactFeatureType) {

})(b2ContactFeatureType = exports.b2ContactFeatureType || (exports.b2ContactFeatureType = {}));
/// The features that intersect to form the contact point
/// This must be 4 bytes or less.
/**
* The features that intersect to form the contact point
* This must be 4 bytes or less.
*/
class b2ContactFeature {

@@ -42,5 +46,9 @@ constructor() {

this.m_key_invalid = false;
/** Feature index on shapeA */
this.m_indexA = 0;
/** Feature index on shapeB */
this.m_indexB = 0;
/** The feature type on shapeA */
this.m_typeA = b2ContactFeatureType.e_vertex;
/** The feature type on shapeB */
this.m_typeB = b2ContactFeatureType.e_vertex;

@@ -93,3 +101,5 @@ }

exports.b2ContactFeature = b2ContactFeature;
/// Contact ids to facilitate warm starting.
/**
* Contact ids to facilitate warm starting.
*/
class b2ContactID {

@@ -114,25 +124,25 @@ constructor() {

exports.b2ContactID = b2ContactID;
/// 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.
/// The local point usage depends on the manifold type:
/// -e_circles: the local center of circleB
/// -e_faceA: the local center of cirlceB or the clip point of polygonB
/// -e_faceB: the clip point of polygonA
/// This structure is stored across time steps, so we keep it small.
/// Note: the impulses are used for internal caching and may not
/// provide reliable contact forces, especially for high speed collisions.
/**
* 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.
* The local point usage depends on the manifold type:
* -e_circles: the local center of circleB
* -e_faceA: the local center of cirlceB or the clip point of polygonB
* -e_faceB: the clip point of polygonA
* This structure is stored across time steps, so we keep it small.
* Note: the impulses are used for internal caching and may not
* provide reliable contact forces, especially for high speed collisions.
*/
class b2ManifoldPoint {
constructor() {
this.localPoint = new b2_math_1.b2Vec2(); /// < usage depends on manifold type
this.normalImpulse = 0; /// < the non-penetration impulse
this.tangentImpulse = 0; /// < the friction impulse
this.id = new b2ContactID(); /// < uniquely identifies a contact point between two shapes
/** Usage depends on manifold type */
this.localPoint = new b2_math_1.b2Vec2();
/** The non-penetration impulse */
this.normalImpulse = 0;
/** The friction impulse */
this.tangentImpulse = 0;
/** Uniquely identifies a contact point between two shapes */
this.id = new b2ContactID();
}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2ManifoldPoint();
return result;
}
Reset() {

@@ -159,24 +169,30 @@ this.localPoint.SetZero();

})(b2ManifoldType = exports.b2ManifoldType || (exports.b2ManifoldType = {}));
/// A manifold for two touching convex shapes.
/// Box2D supports multiple types of contact:
/// - clip point versus plane with radius
/// - point versus point with radius (circles)
/// The local point usage depends on the manifold type:
/// -e_circles: the local center of circleA
/// -e_faceA: the center of faceA
/// -e_faceB: the center of faceB
/// Similarly the local normal usage:
/// -e_circles: not used
/// -e_faceA: the normal on polygonA
/// -e_faceB: the normal on polygonB
/// 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.
/**
* A manifold for two touching convex shapes.
* Box2D supports multiple types of contact:
* - clip point versus plane with radius
* - point versus point with radius (circles)
* The local point usage depends on the manifold type:
* -e_circles: the local center of circleA
* -e_faceA: the center of faceA
* -e_faceB: the center of faceB
* Similarly the local normal usage:
* -e_circles: not used
* -e_faceA: the normal on polygonA
* -e_faceB: the normal on polygonB
* 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.
*/
class b2Manifold {
constructor() {
this.points = b2ManifoldPoint.MakeArray(b2_common_1.b2_maxManifoldPoints);
/** The points of contact */
this.points = b2_common_1.b2MakeArray(b2_common_1.b2_maxManifoldPoints, b2ManifoldPoint);
/** Not use for Type::e_points */
this.localNormal = new b2_math_1.b2Vec2();
/** Usage depends on manifold type */
this.localPoint = new b2_math_1.b2Vec2();
this.type = b2ManifoldType.e_circles;
/** The number of manifold points */
this.pointCount = 0;

@@ -210,6 +226,12 @@ }

exports.b2Manifold = b2Manifold;
/**
* This is used to compute the current state of a contact manifold.
*/
class b2WorldManifold {
constructor() {
/** World vector pointing from A to B */
this.normal = new b2_math_1.b2Vec2();
this.points = b2_math_1.b2Vec2.MakeArray(b2_common_1.b2_maxManifoldPoints);
/** World contact point (point of intersection) */
this.points = b2_common_1.b2MakeArray(b2_common_1.b2_maxManifoldPoints, b2_math_1.b2Vec2);
/** A negative value indicates overlap, in meters */
this.separations = b2_common_1.b2MakeNumberArray(b2_common_1.b2_maxManifoldPoints);

@@ -273,12 +295,20 @@ }

b2WorldManifold.Initialize_s_clipPoint = new b2_math_1.b2Vec2();
/// This is used for determining the state of contact points.
/**
* This is used for determining the state of contact points.
*/
var b2PointState;
(function (b2PointState) {
/** Point does not exist */
b2PointState[b2PointState["b2_nullState"] = 0] = "b2_nullState";
/** Point was added in the update */
b2PointState[b2PointState["b2_addState"] = 1] = "b2_addState";
/** Point persisted across the update */
b2PointState[b2PointState["b2_persistState"] = 2] = "b2_persistState";
/** Point was removed in the update */
b2PointState[b2PointState["b2_removeState"] = 3] = "b2_removeState";
})(b2PointState = exports.b2PointState || (exports.b2PointState = {}));
/// 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.
/**
* 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.
*/
function b2GetPointStates(state1, state2, manifold1, manifold2) {

@@ -290,3 +320,3 @@ // Detect persists and removes.

state1[i] = b2PointState.b2_removeState;
for (let j = 0, jct = manifold2.pointCount; j < jct; ++j) {
for (let j = 0; j < manifold2.pointCount; ++j) {
if (manifold2.points[j].id.key === key) {

@@ -305,3 +335,3 @@ state1[i] = b2PointState.b2_persistState;

state2[i] = b2PointState.b2_addState;
for (let j = 0, jct = manifold1.pointCount; j < jct; ++j) {
for (let j = 0; j < manifold1.pointCount; ++j) {
if (manifold1.points[j].id.key === key) {

@@ -318,3 +348,5 @@ state2[i] = b2PointState.b2_persistState;

exports.b2GetPointStates = b2GetPointStates;
/// Used for computing contact manifolds.
/**
* Used for computing contact manifolds.
*/
class b2ClipVertex {

@@ -325,8 +357,2 @@ constructor() {

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2ClipVertex();
return result;
}
Copy(other) {

@@ -339,3 +365,5 @@ this.v.Copy(other.v);

exports.b2ClipVertex = b2ClipVertex;
/// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
/**
* Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
*/
class b2RayCastInput {

@@ -355,4 +383,6 @@ constructor() {

exports.b2RayCastInput = b2RayCastInput;
/// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
/// come from b2RayCastInput.
/**
* Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
* come from b2RayCastInput.
*/
class b2RayCastOutput {

@@ -370,7 +400,11 @@ constructor() {

exports.b2RayCastOutput = b2RayCastOutput;
/// An axis aligned bounding box.
/**
* An axis aligned bounding box.
*/
class b2AABB {
constructor() {
this.lowerBound = new b2_math_1.b2Vec2(); /// < the lower vertex
this.upperBound = new b2_math_1.b2Vec2(); /// < the upper vertex
/** The lower vertex */
this.lowerBound = new b2_math_1.b2Vec2();
/** The upper vertex */
this.upperBound = new b2_math_1.b2Vec2();
}

@@ -382,3 +416,5 @@ Copy(o) {

}
/// Verify that the bounds are sorted.
/**
* Verify that the bounds are sorted.
*/
IsValid() {

@@ -390,11 +426,17 @@ return (this.lowerBound.IsValid() &&

}
/// Get the center of the AABB.
/**
* Get the center of the AABB.
*/
GetCenter(out) {
return b2_math_1.b2Vec2.Mid(this.lowerBound, this.upperBound, out);
}
/// Get the extents of the AABB (half-widths).
/**
* Get the extents of the AABB (half-widths).
*/
GetExtents(out) {
return b2_math_1.b2Vec2.Extents(this.lowerBound, this.upperBound, out);
}
/// Get the perimeter length
/**
* Get the perimeter length
*/
GetPerimeter() {

@@ -405,3 +447,5 @@ const wx = this.upperBound.x - this.lowerBound.x;

}
/// Combine an AABB into this one.
/**
* Combine an AABB into this one.
*/
Combine1(aabb) {

@@ -414,3 +458,5 @@ this.lowerBound.x = Math.min(this.lowerBound.x, aabb.lowerBound.x);

}
/// Combine two AABBs into this one.
/**
* Combine two AABBs into this one.
*/
Combine2(aabb1, aabb2) {

@@ -427,3 +473,5 @@ this.lowerBound.x = Math.min(aabb1.lowerBound.x, aabb2.lowerBound.x);

}
/// Does this aabb contain the provided AABB.
/**
* Does this aabb contain the provided AABB.
*/
Contains(aabb) {

@@ -541,3 +589,5 @@ return (this.lowerBound.x <= aabb.lowerBound.x &&

exports.b2AABB = b2AABB;
/// Clipping for contact manifolds.
/**
* Clipping for contact manifolds.
*/
function b2ClipSegmentToLine(vOut, [vIn0, vIn1], normal, offset, vertexIndexA) {

@@ -572,8 +622,10 @@ // Start with no output points

exports.b2ClipSegmentToLine = b2ClipSegmentToLine;
/// Determine if two generic shapes overlap.
const b2TestOverlapShape_s_input = new b2_distance_1.b2DistanceInput();
const b2TestOverlapShape_s_simplexCache = new b2_distance_1.b2SimplexCache();
const b2TestOverlapShape_s_output = new b2_distance_1.b2DistanceOutput();
function b2TestOverlapShape(shapeA, indexA, shapeB, indexB, xfA, xfB) {
const input = b2TestOverlapShape_s_input.Reset();
const b2TestOverlap_s_input = new b2_distance_1.b2DistanceInput();
const b2TestOverlap_s_simplexCache = new b2_distance_1.b2SimplexCache();
const b2TestOverlap_s_output = new b2_distance_1.b2DistanceOutput();
/**
* Determine if two generic shapes overlap.
*/
function b2TestOverlap(shapeA, indexA, shapeB, indexB, xfA, xfB) {
const input = b2TestOverlap_s_input.Reset();
input.proxyA.SetShape(shapeA, indexA);

@@ -584,8 +636,8 @@ input.proxyB.SetShape(shapeB, indexB);

input.useRadii = true;
const simplexCache = b2TestOverlapShape_s_simplexCache.Reset();
const simplexCache = b2TestOverlap_s_simplexCache.Reset();
simplexCache.count = 0;
const output = b2TestOverlapShape_s_output.Reset();
const output = b2TestOverlap_s_output.Reset();
b2_distance_1.b2Distance(output, simplexCache, input);
return output.distance < 10 * b2_common_1.b2_epsilon;
}
exports.b2TestOverlapShape = b2TestOverlapShape;
exports.b2TestOverlap = b2TestOverlap;
import { b2Vec2, b2Transform } from "../common/b2_math";
import type { b2Shape } from "./b2_shape";
/**
* A distance proxy is used by the GJK algorithm.
* It encapsulates any shape.
*/
export declare class b2DistanceProxy {

@@ -17,9 +21,21 @@ readonly m_buffer: b2Vec2[];

}
/**
* Used to warm start b2Distance.
* Set count to zero on first call.
*/
export declare class b2SimplexCache {
/** Length or area */
metric: number;
count: number;
/** Vertices on shape A */
readonly indexA: [number, number, number];
/** Vertices on shape B */
readonly indexB: [number, number, number];
Reset(): b2SimplexCache;
}
/**
* Input for b2Distance.
* You have to option to use the shape radii
* in the computation. Even
*/
export declare class b2DistanceInput {

@@ -33,9 +49,18 @@ readonly proxyA: b2DistanceProxy;

}
/**
* Output for b2Distance.
*/
export declare class b2DistanceOutput {
/** Closest point on shapeA */
readonly pointA: b2Vec2;
/** Closest point on shapeB */
readonly pointB: b2Vec2;
distance: number;
/** Number of GJK iterations used */
iterations: number;
Reset(): b2DistanceOutput;
}
/**
* Input parameters for b2ShapeCast
*/
export declare class b2ShapeCastInput {

@@ -48,2 +73,5 @@ readonly proxyA: b2DistanceProxy;

}
/**
* Output results for b2ShapeCast
*/
export declare class b2ShapeCastOutput {

@@ -61,32 +89,10 @@ readonly point: b2Vec2;

};
export declare class b2SimplexVertex {
readonly wA: b2Vec2;
readonly wB: b2Vec2;
readonly w: b2Vec2;
a: number;
indexA: number;
indexB: number;
Copy(other: b2SimplexVertex): b2SimplexVertex;
}
export declare class b2Simplex {
readonly m_v1: b2SimplexVertex;
readonly m_v2: b2SimplexVertex;
readonly m_v3: b2SimplexVertex;
readonly m_vertices: b2SimplexVertex[];
m_count: number;
constructor();
ReadCache(cache: b2SimplexCache, proxyA: b2DistanceProxy, transformA: b2Transform, proxyB: b2DistanceProxy, transformB: b2Transform): void;
WriteCache(cache: b2SimplexCache): void;
GetSearchDirection(out: b2Vec2): b2Vec2;
GetClosestPoint(out: b2Vec2): b2Vec2;
GetWitnessPoints(pA: b2Vec2, pB: b2Vec2): void;
GetMetric(): number;
Solve2(): void;
Solve3(): void;
private static s_e12;
private static s_e13;
private static s_e23;
}
export declare function b2Distance(output: b2DistanceOutput, cache: b2SimplexCache, input: b2DistanceInput): void;
/**
* Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
* GJK-raycast
* Algorithm by Gino van den Bergen.
* "Smooth Mesh Contacts with GJK" in Game Physics Pearls. 2010
*/
export declare function b2ShapeCast(output: b2ShapeCastOutput, input: b2ShapeCastInput): boolean;
//# sourceMappingURL=b2_distance.d.ts.map

@@ -20,11 +20,13 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2ShapeCast = exports.b2Distance = exports.b2Simplex = exports.b2SimplexVertex = exports.b2Gjk = exports.b2ShapeCastOutput = exports.b2ShapeCastInput = exports.b2DistanceOutput = exports.b2DistanceInput = exports.b2SimplexCache = exports.b2DistanceProxy = void 0;
exports.b2ShapeCast = exports.b2Distance = exports.b2Gjk = exports.b2ShapeCastOutput = exports.b2ShapeCastInput = exports.b2DistanceOutput = exports.b2DistanceInput = exports.b2SimplexCache = exports.b2DistanceProxy = void 0;
// DEBUG: import { b2Assert } from "../common/b2_common";
const b2_common_1 = require("../common/b2_common");
const b2_math_1 = require("../common/b2_math");
/// A distance proxy is used by the GJK algorithm.
/// It encapsulates any shape.
/**
* A distance proxy is used by the GJK algorithm.
* It encapsulates any shape.
*/
class b2DistanceProxy {
constructor() {
this.m_buffer = b2_math_1.b2Vec2.MakeArray(2);
this.m_buffer = b2_common_1.b2MakeArray(2, b2_math_1.b2Vec2);
this.m_vertices = this.m_buffer;

@@ -94,10 +96,15 @@ this.m_count = 0;

exports.b2DistanceProxy = b2DistanceProxy;
/// Used to warm start b2Distance.
/// Set count to zero on first call.
/**
* Used to warm start b2Distance.
* Set count to zero on first call.
*/
class b2SimplexCache {
constructor() {
this.metric = 0; /// < length or area
/** Length or area */
this.metric = 0;
this.count = 0;
this.indexA = [0, 0, 0]; /// < vertices on shape A
this.indexB = [0, 0, 0]; /// < vertices on shape B
/** Vertices on shape A */
this.indexA = [0, 0, 0];
/** Vertices on shape B */
this.indexB = [0, 0, 0];
}

@@ -111,5 +118,7 @@ Reset() {

exports.b2SimplexCache = b2SimplexCache;
/// Input for b2Distance.
/// You have to option to use the shape radii
/// in the computation. Even
/**
* Input for b2Distance.
* You have to option to use the shape radii
* in the computation. Even
*/
class b2DistanceInput {

@@ -133,9 +142,14 @@ constructor() {

exports.b2DistanceInput = b2DistanceInput;
/// Output for b2Distance.
/**
* Output for b2Distance.
*/
class b2DistanceOutput {
constructor() {
this.pointA = new b2_math_1.b2Vec2(); /// < closest point on shapeA
this.pointB = new b2_math_1.b2Vec2(); /// < closest point on shapeB
/** Closest point on shapeA */
this.pointA = new b2_math_1.b2Vec2();
/** Closest point on shapeB */
this.pointB = new b2_math_1.b2Vec2();
this.distance = 0;
this.iterations = 0; /// < number of GJK iterations used
/** Number of GJK iterations used */
this.iterations = 0;
}

@@ -151,3 +165,5 @@ Reset() {

exports.b2DistanceOutput = b2DistanceOutput;
/// Input parameters for b2ShapeCast
/**
* Input parameters for b2ShapeCast
*/
class b2ShapeCastInput {

@@ -163,3 +179,5 @@ constructor() {

exports.b2ShapeCastInput = b2ShapeCastInput;
/// Output results for b2ShapeCast
/**
* Output results for b2ShapeCast
*/
class b2ShapeCastOutput {

@@ -169,3 +187,3 @@ constructor() {

this.normal = new b2_math_1.b2Vec2();
this.lambda = 0.0;
this.lambda = 0;
this.iterations = 0;

@@ -204,3 +222,2 @@ }

}
exports.b2SimplexVertex = b2SimplexVertex;
class b2Simplex {

@@ -211,12 +228,7 @@ constructor() {

this.m_v3 = new b2SimplexVertex();
this.m_vertices = [
/* 3 */
];
this.m_count = 0;
this.m_vertices[0] = this.m_v1;
this.m_vertices[1] = this.m_v2;
this.m_vertices[2] = this.m_v3;
this.m_vertices = [this.m_v1, this.m_v2, this.m_v3];
}
ReadCache(cache, proxyA, transformA, proxyB, transformB) {
// DEBUG: b2Assert(0 <= cache.count && cache.count <= 3);
// DEBUG: b2Assert(cache.count <= 3);
// Copy data from cache.

@@ -463,3 +475,2 @@ this.m_count = cache.count;

}
exports.b2Simplex = b2Simplex;
b2Simplex.s_e12 = new b2_math_1.b2Vec2();

@@ -508,5 +519,4 @@ b2Simplex.s_e13 = new b2_math_1.b2Vec2();

break;
default:
// DEBUG: b2Assert(false);
break;
// DEBUG: default:
// DEBUG: b2Assert(false);
}

@@ -584,7 +594,2 @@ // If we have 3 points, then the origin is in the corresponding triangle.

exports.b2Distance = b2Distance;
/// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
// GJK-raycast
// Algorithm by Gino van den Bergen.
// "Smooth Mesh Contacts with GJK" in Game Physics Pearls. 2010
// bool b2ShapeCast(b2ShapeCastOutput* output, const b2ShapeCastInput* input);
const b2ShapeCast_s_n = new b2_math_1.b2Vec2();

@@ -598,5 +603,11 @@ const b2ShapeCast_s_simplex = new b2Simplex();

const b2ShapeCast_s_pointB = new b2_math_1.b2Vec2();
/**
* Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
* GJK-raycast
* Algorithm by Gino van den Bergen.
* "Smooth Mesh Contacts with GJK" in Game Physics Pearls. 2010
*/
function b2ShapeCast(output, input) {
output.iterations = 0;
output.lambda = 1.0;
output.lambda = 1;
output.normal.SetZero();

@@ -612,3 +623,3 @@ output.point.SetZero();

const n = b2ShapeCast_s_n.SetZero();
let lambda = 0.0;
let lambda = 0;
// Initial simplex

@@ -654,3 +665,3 @@ const simplex = b2ShapeCast_s_simplex;

}
n.Copy(v).Negate();
b2_math_1.b2Vec2.Negate(v, n);
simplex.m_count = 0;

@@ -664,7 +675,7 @@ }

vertex.indexA = indexB;
vertex.wA.Copy(wB).AddScaled(lambda, r);
b2_math_1.b2Vec2.AddScaled(wB, lambda, r, vertex.wA);
vertex.indexB = indexA;
vertex.wB.Copy(wA);
vertex.w.Copy(vertex.wB).Subtract(vertex.wA);
vertex.a = 1.0;
b2_math_1.b2Vec2.Subtract(vertex.wB, vertex.wA, vertex.w);
vertex.a = 1;
simplex.m_count += 1;

@@ -680,3 +691,3 @@ switch (simplex.m_count) {

break;
default:
// DEBUG: default:
// DEBUG: b2Assert(false);

@@ -703,6 +714,6 @@ }

if (v.LengthSquared() > 0) {
n.Copy(v).Negate();
b2_math_1.b2Vec2.Negate(v, n);
n.Normalize();
}
output.point.Copy(pointA).AddScaled(radiusA, n);
b2_math_1.b2Vec2.AddScaled(pointA, radiusA, n, output.point);
output.normal.Copy(n);

@@ -709,0 +720,0 @@ output.lambda = lambda;

import { b2Vec2, XY } from "../common/b2_math";
import { b2AABB, b2RayCastInput } from "./b2_collision";
/**
* A node in the dynamic tree. The client does not interact with this directly.
*/
export declare class b2TreeNode<T> {
readonly m_id: number;
readonly id: number;
/** Enlarged AABB */
readonly aabb: b2AABB;

@@ -20,28 +24,31 @@ userData: T | null;

}
/**
* 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 b2_fatAABBFactor
* 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
*/
export declare class b2DynamicTree<T> {
m_root: b2TreeNode<T> | null;
m_freeList: b2TreeNode<T> | null;
m_path: number;
m_insertionCount: number;
private m_root;
private m_freeList;
Query(aabb: b2AABB, callback: (node: b2TreeNode<T>) => boolean): void;
QueryPoint(point: XY, callback: (node: b2TreeNode<T>) => boolean): void;
RayCast(input: b2RayCastInput, callback: (input: b2RayCastInput, node: b2TreeNode<T>) => number): void;
AllocateNode(): b2TreeNode<T>;
FreeNode(node: b2TreeNode<T>): void;
private AllocateNode;
private FreeNode;
CreateProxy(aabb: b2AABB, userData: T): b2TreeNode<T>;
DestroyProxy(node: b2TreeNode<T>): void;
MoveProxy(node: b2TreeNode<T>, aabb: b2AABB, displacement: b2Vec2): boolean;
InsertLeaf(leaf: b2TreeNode<T>): void;
RemoveLeaf(leaf: b2TreeNode<T>): void;
Balance(A: b2TreeNode<T>): b2TreeNode<T>;
private InsertLeaf;
private RemoveLeaf;
private Balance;
GetHeight(): number;
GetAreaRatio(): number;
ComputeHeight(): number;
ValidateStructure(node: b2TreeNode<T> | null): void;
ValidateMetrics(node: b2TreeNode<T> | null): void;
Validate(): void;
GetMaxBalance(): number;
RebuildBottomUp(): void;
ShiftOrigin(newOrigin: XY): void;
}
//# sourceMappingURL=b2_dynamic_tree.d.ts.map

@@ -41,5 +41,8 @@ "use strict";

let nextNodeid = 0;
/// A node in the dynamic tree. The client does not interact with this directly.
/**
* A node in the dynamic tree. The client does not interact with this directly.
*/
class b2TreeNode {
constructor() {
/** Enlarged AABB */
this.aabb = new b2_collision_1.b2AABB();

@@ -52,3 +55,3 @@ this.userData = null;

this.moved = false;
this.m_id = nextNodeid++;
this.id = nextNodeid++;
}

@@ -99,10 +102,12 @@ Reset() {

exports.b2TreeNode = b2TreeNode;
/// 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 b2_fatAABBFactor
/// 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
/**
* 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 b2_fatAABBFactor
* 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
*/
class b2DynamicTree {

@@ -112,4 +117,2 @@ constructor() {

this.m_freeList = null;
this.m_path = 0;
this.m_insertionCount = 0;
}

@@ -168,4 +171,4 @@ Query(aabb, callback) {

// Build a bounding box for the segment.
const { segmentAABB, subInput, c, h } = temp;
const t = temp.t.Set(p1.x + maxFraction * (p2.x - p1.x), p1.y + maxFraction * (p2.y - p1.y));
const { segmentAABB, subInput, c, h, t } = temp;
b2_math_1.b2Vec2.AddScaled(p1, maxFraction, b2_math_1.b2Vec2.Subtract(p2, p1, t), t);
b2_math_1.b2Vec2.Min(p1, t, segmentAABB.lowerBound);

@@ -202,3 +205,3 @@ b2_math_1.b2Vec2.Max(p1, t, segmentAABB.upperBound);

maxFraction = value;
t.Set(p1.x + maxFraction * (p2.x - p1.x), p1.y + maxFraction * (p2.y - p1.y));
b2_math_1.b2Vec2.AddScaled(p1, maxFraction, b2_math_1.b2Vec2.Subtract(p2, p1, t), t);
b2_math_1.b2Vec2.Min(p1, t, segmentAABB.lowerBound);

@@ -237,4 +240,5 @@ b2_math_1.b2Vec2.Max(p1, t, segmentAABB.upperBound);

// Fatten the aabb.
node.aabb.lowerBound.Set(aabb.lowerBound.x - b2_common_1.b2_aabbExtension, aabb.lowerBound.y - b2_common_1.b2_aabbExtension);
node.aabb.upperBound.Set(aabb.upperBound.x + b2_common_1.b2_aabbExtension, aabb.upperBound.y + b2_common_1.b2_aabbExtension);
const r = b2_common_1.b2_aabbExtension;
node.aabb.lowerBound.Set(aabb.lowerBound.x - r, aabb.lowerBound.y - r);
node.aabb.upperBound.Set(aabb.upperBound.x + r, aabb.upperBound.y + r);
node.userData = userData;

@@ -255,8 +259,9 @@ node.height = 0;

const { fatAABB, hugeAABB } = temp;
fatAABB.lowerBound.Set(aabb.lowerBound.x - b2_common_1.b2_aabbExtension, aabb.lowerBound.y - b2_common_1.b2_aabbExtension);
fatAABB.upperBound.Set(aabb.upperBound.x + b2_common_1.b2_aabbExtension, aabb.upperBound.y + b2_common_1.b2_aabbExtension);
const r = b2_common_1.b2_aabbExtension;
fatAABB.lowerBound.Set(aabb.lowerBound.x - r, aabb.lowerBound.y - r);
fatAABB.upperBound.Set(aabb.upperBound.x + r, aabb.upperBound.y + r);
// Predict AABB movement
const d_x = b2_common_1.b2_aabbMultiplier * displacement.x;
const d_y = b2_common_1.b2_aabbMultiplier * displacement.y;
if (d_x < 0.0) {
if (d_x < 0) {
fatAABB.lowerBound.x += d_x;

@@ -267,3 +272,3 @@ }

}
if (d_y < 0.0) {
if (d_y < 0) {
fatAABB.lowerBound.y += d_y;

@@ -296,3 +301,2 @@ }

InsertLeaf(leaf) {
++this.m_insertionCount;
if (this.m_root === null) {

@@ -401,3 +405,3 @@ this.m_root = leaf;

const parent = b2_common_1.b2Verify(leaf.parent);
const grandParent = parent === null || parent === void 0 ? void 0 : parent.parent;
const grandParent = parent.parent;
const sibling = b2_common_1.b2Verify(parent.child1 === leaf ? parent.child2 : parent.child1);

@@ -415,10 +419,10 @@ if (grandParent !== null) {

// Adjust ancestor bounds.
let index = grandParent;
while (index !== null) {
index = this.Balance(index);
const child1 = b2_common_1.b2Verify(index.child1);
const child2 = b2_common_1.b2Verify(index.child2);
index.aabb.Combine2(child1.aabb, child2.aabb);
index.height = 1 + Math.max(child1.height, child2.height);
index = index.parent;
let node = grandParent;
while (node !== null) {
node = this.Balance(node);
const child1 = b2_common_1.b2Verify(node.child1);
const child2 = b2_common_1.b2Verify(node.child2);
node.aabb.Combine2(child1.aabb, child2.aabb);
node.height = 1 + Math.max(child1.height, child2.height);
node = node.parent;
}

@@ -542,64 +546,2 @@ }

}
ComputeHeight() {
if (this.m_root === null) {
return 0;
}
const height = this.m_root.ComputeHeight();
return height;
}
ValidateStructure(node) {
if (node === null) {
return;
}
if (node === this.m_root) {
// DEBUG: b2Assert(node.parent === null);
}
if (node.IsLeaf()) {
// DEBUG: b2Assert(node.child1 === null);
// DEBUG: b2Assert(node.child2 === null);
// DEBUG: b2Assert(node.height === 0);
return;
}
const child1 = b2_common_1.b2Verify(node.child1);
const child2 = b2_common_1.b2Verify(node.child2);
// DEBUG: b2Assert(child1.parent === index);
// DEBUG: b2Assert(child2.parent === index);
this.ValidateStructure(child1);
this.ValidateStructure(child2);
}
ValidateMetrics(node) {
if (node === null) {
return;
}
if (node.IsLeaf()) {
// DEBUG: b2Assert(node.child1 === null);
// DEBUG: b2Assert(node.child2 === null);
// DEBUG: b2Assert(node.height === 0);
return;
}
const child1 = b2_common_1.b2Verify(node.child1);
const child2 = b2_common_1.b2Verify(node.child2);
// DEBUG: const height1 = child1.height;
// DEBUG: const height2 = child2.height;
// DEBUG: const height = 1 + Math.max(height1, height2);
// DEBUG: b2Assert(node.height === height);
// DEBUG: const { aabb } = temp;
// DEBUG: aabb.Combine2(child1.aabb, child2.aabb);
// DEBUG: b2Assert(aabb.lowerBound === node.aabb.lowerBound);
// DEBUG: b2Assert(aabb.upperBound === node.aabb.upperBound);
this.ValidateMetrics(child1);
this.ValidateMetrics(child2);
}
Validate() {
// DEBUG: this.ValidateStructure(this.m_root);
// DEBUG: this.ValidateMetrics(this.m_root);
// let freeCount = 0;
// let freeIndex: b2TreeNode<T> | null = this.m_freeList;
// while (freeIndex !== null) {
// freeIndex = freeIndex.parent; // freeIndex = freeIndex.next;
// ++freeCount;
// }
// DEBUG: b2Assert(this.GetHeight() === this.ComputeHeight());
// b2Assert(this.m_nodeCount + freeCount === this.m_nodeCapacity);
}
GetMaxBalance() {

@@ -611,69 +553,2 @@ if (this.m_root === null) {

}
/// Build an optimal tree. Very expensive. For testing.
RebuildBottomUp() {
/*
int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
int32 count = 0;
// Build array of leaves. Free the rest.
for (int32 i = 0; i < m_nodeCapacity; ++i) {
if (m_nodes[i].height < 0) {
// free node in pool
continue;
}
if (m_nodes[i].IsLeaf()) {
m_nodes[i].parent = b2_nullNode;
nodes[count] = i;
++count;
} else {
FreeNode(i);
}
}
while (count > 1) {
float32 minCost = b2_maxFloat;
int32 iMin = -1, jMin = -1;
for (int32 i = 0; i < count; ++i) {
b2AABB aabbi = m_nodes[nodes[i]].aabb;
for (int32 j = i + 1; j < count; ++j) {
b2AABB aabbj = m_nodes[nodes[j]].aabb;
b2AABB b;
b.Combine(aabbi, aabbj);
float32 cost = b.GetPerimeter();
if (cost < minCost) {
iMin = i;
jMin = j;
minCost = cost;
}
}
}
int32 index1 = nodes[iMin];
int32 index2 = nodes[jMin];
b2TreeNode<T>* child1 = m_nodes + index1;
b2TreeNode<T>* child2 = m_nodes + index2;
int32 parentIndex = AllocateNode();
b2TreeNode<T>* parent = m_nodes + parentIndex;
parent.child1 = index1;
parent.child2 = index2;
parent.height = 1 + Math.max(child1.height, child2.height);
parent.aabb.Combine(child1.aabb, child2.aabb);
parent.parent = b2_nullNode;
child1.parent = parentIndex;
child2.parent = parentIndex;
nodes[jMin] = nodes[count-1];
nodes[iMin] = parentIndex;
--count;
}
m_root = nodes[0];
b2Free(nodes);
*/
this.Validate();
}
ShiftOrigin(newOrigin) {

@@ -680,0 +555,0 @@ var _a;

@@ -0,1 +1,2 @@

import { b2Color, b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Transform, XY } from "../common/b2_math";

@@ -5,14 +6,40 @@ import { b2AABB, b2RayCastInput, b2RayCastOutput } from "./b2_collision";

import { b2MassData, b2Shape } from "./b2_shape";
/**
* A line segment (edge) shape. These can be connected in chains or loops
* to other edge shapes. Edges created independently are two-sided and do
* no provide smooth movement across junctions.
*/
export declare class b2EdgeShape extends b2Shape {
/** These are the edge vertices */
readonly m_vertex1: b2Vec2;
readonly m_vertex2: b2Vec2;
/** Optional adjacent vertices. These are used for smooth collision. */
readonly m_vertex0: b2Vec2;
readonly m_vertex3: b2Vec2;
/** Uses m_vertex0 and m_vertex3 to create smooth collision. */
m_oneSided: boolean;
constructor();
/**
* Set this as a part of a sequence. Vertex v0 precedes the edge and vertex v3
* follows. These extra vertices are used to provide smooth movement
* across junctions. This also makes the collision one-sided. The edge
* normal points to the right looking from v1 to v2.
*/
SetOneSided(v0: XY, v1: XY, v2: XY, v3: XY): b2EdgeShape;
/**
* Set this as an isolated edge. Collision is two-sided.
*/
SetTwoSided(v1: XY, v2: XY): b2EdgeShape;
/**
* Implement b2Shape.
*/
Clone(): b2EdgeShape;
Copy(other: b2EdgeShape): b2EdgeShape;
/**
* @see b2Shape::GetChildCount
*/
GetChildCount(): number;
/**
* @see b2Shape::TestPoint
*/
TestPoint(_xf: b2Transform, _p: XY): boolean;

@@ -25,9 +52,24 @@ private static RayCast_s_p1;

private static RayCast_s_r;
/**
* Implement b2Shape.
*
* p = p1 + t * d
* v = v1 + s * e
* p1 + t * d = v1 + s * e
* s * e - t * d = p1 - v1
*/
RayCast(output: b2RayCastOutput, input: b2RayCastInput, xf: b2Transform, _childIndex: number): boolean;
private static ComputeAABB_s_v1;
private static ComputeAABB_s_v2;
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb: b2AABB, xf: b2Transform, _childIndex: number): void;
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData: b2MassData, _density: number): void;
SetupDistanceProxy(proxy: b2DistanceProxy, _index: number): void;
Draw(draw: b2Draw, color: b2Color): void;
}
//# sourceMappingURL=b2_edge_shape.d.ts.map

@@ -25,22 +25,25 @@ "use strict";

const b2_shape_1 = require("./b2_shape");
/// A line segment (edge) shape. These can be connected in chains or loops
/// to other edge shapes. Edges created independently are two-sided and do
/// no provide smooth movement across junctions.
/**
* A line segment (edge) shape. These can be connected in chains or loops
* to other edge shapes. Edges created independently are two-sided and do
* no provide smooth movement across junctions.
*/
class b2EdgeShape extends b2_shape_1.b2Shape {
constructor() {
super(b2_shape_1.b2ShapeType.e_edge, b2_common_1.b2_polygonRadius);
/// These are the edge vertices
/** These are the edge vertices */
this.m_vertex1 = new b2_math_1.b2Vec2();
this.m_vertex2 = new b2_math_1.b2Vec2();
/// Optional adjacent vertices. These are used for smooth collision.
/** Optional adjacent vertices. These are used for smooth collision. */
this.m_vertex0 = new b2_math_1.b2Vec2();
this.m_vertex3 = new b2_math_1.b2Vec2();
/// Uses m_vertex0 and m_vertex3 to create smooth collision.
/** Uses m_vertex0 and m_vertex3 to create smooth collision. */
this.m_oneSided = false;
}
/// Set this as a part of a sequence. Vertex v0 precedes the edge and vertex v3
/// follows. These extra vertices are used to provide smooth movement
/// across junctions. This also makes the collision one-sided. The edge
/// normal points to the right looking from v1 to v2.
// void SetOneSided(const b2Vec2& v0, const b2Vec2& v1,const b2Vec2& v2, const b2Vec2& v3);
/**
* Set this as a part of a sequence. Vertex v0 precedes the edge and vertex v3
* follows. These extra vertices are used to provide smooth movement
* across junctions. This also makes the collision one-sided. The edge
* normal points to the right looking from v1 to v2.
*/
SetOneSided(v0, v1, v2, v3) {

@@ -54,3 +57,5 @@ this.m_vertex0.Copy(v0);

}
/// Set this as an isolated edge. Collision is two-sided.
/**
* Set this as an isolated edge. Collision is two-sided.
*/
SetTwoSided(v1, v2) {

@@ -62,3 +67,5 @@ this.m_vertex1.Copy(v1);

}
/// Implement b2Shape.
/**
* Implement b2Shape.
*/
Clone() {

@@ -77,10 +84,22 @@ return new b2EdgeShape().Copy(this);

}
/// @see b2Shape::GetChildCount
/**
* @see b2Shape::GetChildCount
*/
GetChildCount() {
return 1;
}
/// @see b2Shape::TestPoint
/**
* @see b2Shape::TestPoint
*/
TestPoint(_xf, _p) {
return false;
}
/**
* Implement b2Shape.
*
* p = p1 + t * d
* v = v1 + s * e
* p1 + t * d = v1 + s * e
* s * e - t * d = p1 - v1
*/
RayCast(output, input, xf, _childIndex) {

@@ -131,2 +150,5 @@ // Put the ray into the edge's frame of reference.

}
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb, xf, _childIndex) {

@@ -141,3 +163,5 @@ const v1 = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertex1, b2EdgeShape.ComputeAABB_s_v1);

}
/// @see b2Shape::ComputeMass
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData, _density) {

@@ -155,9 +179,13 @@ massData.mass = 0;

}
Draw(draw, color) {
const v1 = this.m_vertex1;
const v2 = this.m_vertex2;
draw.DrawSegment(v1, v2, color);
if (this.m_oneSided === false) {
draw.DrawPoint(v1, 4, color);
draw.DrawPoint(v2, 4, color);
}
}
}
exports.b2EdgeShape = b2EdgeShape;
/// Implement b2Shape.
// p = p1 + t * d
// v = v1 + s * e
// p1 + t * d = v1 + s * e
// s * e - t * d = p1 - v1
b2EdgeShape.RayCast_s_p1 = new b2_math_1.b2Vec2();

@@ -169,4 +197,3 @@ b2EdgeShape.RayCast_s_p2 = new b2_math_1.b2Vec2();

b2EdgeShape.RayCast_s_r = new b2_math_1.b2Vec2();
/// @see b2Shape::ComputeAABB
b2EdgeShape.ComputeAABB_s_v1 = new b2_math_1.b2Vec2();
b2EdgeShape.ComputeAABB_s_v2 = new b2_math_1.b2Vec2();

@@ -0,1 +1,2 @@

import { b2Color, b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Transform, XY } from "../common/b2_math";

@@ -5,2 +6,8 @@ import { b2AABB, b2RayCastInput, b2RayCastOutput } from "./b2_collision";

import { b2MassData, b2Shape } from "./b2_shape";
/**
* A solid convex polygon. It is assumed that the interior of the polygon is to
* the left of each edge.
* Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
* In most cases you should not need many vertices for a convex polygon.
*/
export declare class b2PolygonShape extends b2Shape {

@@ -12,17 +19,51 @@ readonly m_centroid: b2Vec2;

constructor();
/**
* Implement b2Shape.
*/
Clone(): b2PolygonShape;
Copy(other: b2PolygonShape): b2PolygonShape;
/**
* @see b2Shape::GetChildCount
*/
GetChildCount(): number;
Set(vertices: XY[]): b2PolygonShape;
Set(vertices: XY[], count: number): b2PolygonShape;
Set(vertices: number[]): b2PolygonShape;
SetEx(vertices: (index: number) => XY, count: number): b2PolygonShape;
/**
* Create a convex hull from the given array of points.
*
* @warning the points may be re-ordered, even if they form a convex polygon
* @warning collinear points are handled but not removed. Collinear points
* may lead to poor stacking behavior.
*/
Set(vertices: XY[], count?: number): b2PolygonShape;
/**
* Build vertices to represent an axis-aligned box or an oriented box.
*
* @param hx The half-width.
* @param hy The half-height.
* @param center The center of the box in local coordinates.
* @param angle The rotation of the box in local coordinates.
*/
SetAsBox(hx: number, hy: number, center?: XY, angle?: number): b2PolygonShape;
/**
* @see b2Shape::TestPoint
*/
TestPoint(xf: b2Transform, p: XY): boolean;
/**
* Implement b2Shape.
*
* @note because the polygon is solid, rays that start inside do not hit because the normal is
* not defined.
*/
RayCast(output: b2RayCastOutput, input: b2RayCastInput, xf: b2Transform, _childIndex: number): boolean;
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb: b2AABB, xf: b2Transform, _childIndex: number): void;
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData: b2MassData, density: number): void;
Validate(): boolean;
SetupDistanceProxy(proxy: b2DistanceProxy, _index: number): void;
Draw(draw: b2Draw, color: b2Color): void;
}
//# sourceMappingURL=b2_polygon_shape.d.ts.map

@@ -79,3 +79,3 @@ "use strict";

b2_math_1.b2Vec2.Subtract(vs[i], s, p2);
b2_math_1.b2Vec2.Subtract(vs[(i + 1) % count], s, p3);
b2_math_1.b2Vec2.Subtract(vs[i + 1 < count ? i + 1 : 0], s, p3);
b2_math_1.b2Vec2.Subtract(p2, p1, e1);

@@ -97,5 +97,8 @@ b2_math_1.b2Vec2.Subtract(p3, p1, e2);

}
/// A solid convex polygon. It is assumed that the interior of the polygon is to
/// the left of each edge.
/// In most cases you should not need many vertices for a convex polygon.
/**
* A solid convex polygon. It is assumed that the interior of the polygon is to
* the left of each edge.
* Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
* In most cases you should not need many vertices for a convex polygon.
*/
class b2PolygonShape extends b2_shape_1.b2Shape {

@@ -109,3 +112,5 @@ constructor() {

}
/// Implement b2Shape.
/**
* Implement b2Shape.
*/
Clone() {

@@ -119,4 +124,4 @@ return new b2PolygonShape().Copy(this);

this.m_count = other.m_count;
this.m_vertices = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_normals = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_vertices = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_normals = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
for (let i = 0; i < this.m_count; ++i) {

@@ -128,17 +133,16 @@ this.m_vertices[i].Copy(other.m_vertices[i]);

}
/// @see b2Shape::GetChildCount
/**
* @see b2Shape::GetChildCount
*/
GetChildCount() {
return 1;
}
Set(...args) {
if (typeof args[0][0] === "number") {
const vertices = args[0];
b2_common_1.b2Assert(vertices.length % 2 === 0);
return this.SetEx((index) => ({ x: vertices[index * 2], y: vertices[index * 2 + 1] }), vertices.length / 2);
}
const vertices = args[0];
const count = args[1] || vertices.length;
return this.SetEx((index) => vertices[index], count);
}
SetEx(vertices, count) {
/**
* Create a convex hull from the given array of points.
*
* @warning the points may be re-ordered, even if they form a convex polygon
* @warning collinear points are handled but not removed. Collinear points
* may lead to poor stacking behavior.
*/
Set(vertices, count = vertices.length) {
// DEBUG: b2Assert(3 <= count && count <= b2_maxPolygonVertices);

@@ -152,3 +156,3 @@ if (count < 3) {

for (let i = 0; i < n; ++i) {
const v = vertices(i);
const v = vertices[i];
const unique = ps.every((p) => b2_math_1.b2Vec2.DistanceSquared(v, p) >= weldingDistanceSquared);

@@ -208,4 +212,4 @@ if (unique) {

this.m_count = m;
this.m_vertices = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_normals = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_vertices = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_normals = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
// Copy vertices.

@@ -217,5 +221,5 @@ for (let i = 0; i < m; ++i) {

for (let i = 0; i < m; ++i) {
const vertexi1 = this.m_vertices[i];
const vertexi2 = this.m_vertices[(i + 1) % m];
const edge = b2_math_1.b2Vec2.Subtract(vertexi2, vertexi1, b2_math_1.b2Vec2.s_t0);
const i1 = i;
const i2 = i + 1 < m ? i + 1 : 0;
const edge = b2_math_1.b2Vec2.Subtract(this.m_vertices[i2], this.m_vertices[i1], b2_math_1.b2Vec2.s_t0);
// DEBUG: b2Assert(edge.LengthSquared() > b2_epsilon_sq);

@@ -228,11 +232,14 @@ b2_math_1.b2Vec2.CrossVec2One(edge, this.m_normals[i]).Normalize();

}
/// Build vertices to represent an axis-aligned box or an oriented box.
/// @param hx the half-width.
/// @param hy the half-height.
/// @param center the center of the box in local coordinates.
/// @param angle the rotation of the box in local coordinates.
/**
* Build vertices to represent an axis-aligned box or an oriented box.
*
* @param hx The half-width.
* @param hy The half-height.
* @param center The center of the box in local coordinates.
* @param angle The rotation of the box in local coordinates.
*/
SetAsBox(hx, hy, center, angle = 0) {
this.m_count = 4;
this.m_vertices = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_normals = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_vertices = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_normals = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_vertices[0].Set(-hx, -hy);

@@ -246,3 +253,2 @@ this.m_vertices[1].Set(hx, -hy);

this.m_normals[3].Set(-1, 0);
this.m_centroid.SetZero();
if (center) {

@@ -259,5 +265,10 @@ this.m_centroid.Copy(center);

}
else {
this.m_centroid.SetZero();
}
return this;
}
/// @see b2Shape::TestPoint
/**
* @see b2Shape::TestPoint
*/
TestPoint(xf, p) {

@@ -273,5 +284,8 @@ const pLocal = b2_math_1.b2Transform.TransposeMultiplyVec2(xf, p, temp.TestPoint.pLocal);

}
/// Implement b2Shape.
/// @note because the polygon is solid, rays that start inside do not hit because the normal is
/// not defined.
/**
* Implement b2Shape.
*
* @note because the polygon is solid, rays that start inside do not hit because the normal is
* not defined.
*/
RayCast(output, input, xf, _childIndex) {

@@ -327,3 +341,5 @@ // Put the ray into the polygon's frame of reference.

}
/// @see b2Shape::ComputeAABB
/**
* @see b2Shape::ComputeAABB
*/
ComputeAABB(aabb, xf, _childIndex) {

@@ -334,4 +350,4 @@ const lower = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertices[0], aabb.lowerBound);

const v = b2_math_1.b2Transform.MultiplyVec2(xf, this.m_vertices[i], temp.ComputeAABB.v);
b2_math_1.b2Vec2.Min(v, lower, lower);
b2_math_1.b2Vec2.Max(v, upper, upper);
b2_math_1.b2Vec2.Min(lower, v, lower);
b2_math_1.b2Vec2.Max(upper, v, upper);
}

@@ -342,3 +358,5 @@ const r = this.m_radius;

}
/// @see b2Shape::ComputeMass
/**
* @see b2Shape::ComputeMass
*/
ComputeMass(massData, density) {

@@ -379,3 +397,3 @@ // Polygon mass, centroid, and inertia.

const e1 = b2_math_1.b2Vec2.Subtract(this.m_vertices[i], s, temp.ComputeMass.e1);
const e2 = b2_math_1.b2Vec2.Subtract(this.m_vertices[(i + 1) % this.m_count], s, temp.ComputeMass.e2);
const e2 = b2_math_1.b2Vec2.Subtract(this.m_vertices[i + 1 < this.m_count ? i + 1 : 0], s, temp.ComputeMass.e2);
const D = b2_math_1.b2Vec2.Cross(e1, e2);

@@ -385,3 +403,3 @@ const triangleArea = 0.5 * D;

// Area weighted centroid
center.Add(b2_math_1.b2Vec2.Scale(triangleArea * k_inv3, b2_math_1.b2Vec2.Add(e1, e2, b2_math_1.b2Vec2.s_t0), b2_math_1.b2Vec2.s_t1));
center.AddScaled(triangleArea * k_inv3, b2_math_1.b2Vec2.Add(e1, e2, b2_math_1.b2Vec2.s_t0));
const ex1 = e1.x;

@@ -410,3 +428,3 @@ const ey1 = e1.y;

const i1 = i;
const i2 = (i + 1) % this.m_count;
const i2 = i < this.m_count - 1 ? i1 + 1 : 0;
const p = this.m_vertices[i1];

@@ -432,3 +450,8 @@ b2_math_1.b2Vec2.Subtract(this.m_vertices[i2], p, e);

}
Draw(draw, color) {
const vertexCount = this.m_count;
const vertices = this.m_vertices;
draw.DrawSolidPolygon(vertices, vertexCount, color);
}
}
exports.b2PolygonShape = b2PolygonShape;

@@ -0,7 +1,14 @@

import { b2Color, b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Transform, XY } from "../common/b2_math";
import { b2AABB, b2RayCastInput, b2RayCastOutput } from "./b2_collision";
import { b2DistanceProxy } from "./b2_distance";
/**
* This holds the mass data computed for a shape.
*/
export declare class b2MassData {
/** The mass of the shape, usually in kilograms. */
mass: number;
/** The position of the shape's centroid relative to the shape's origin. */
readonly center: b2Vec2;
/** The rotational inertia of the shape about the local origin. */
I: number;

@@ -17,16 +24,65 @@ }

}
/**
* A shape is used for collision detection. You can create a shape however you like.
* Shapes used for simulation in b2World are created automatically when a b2Fixture
* is created. Shapes may encapsulate a one or more child shapes.
*/
export declare abstract class b2Shape {
readonly m_type: b2ShapeType;
/**
* Radius of a shape. For polygonal shapes this must be b2_polygonRadius. There is no support for
* making rounded polygons.
*/
m_radius: number;
constructor(type: b2ShapeType, radius: number);
/**
* Clone the concrete shape.
*/
abstract Clone(): b2Shape;
Copy(other: b2Shape): b2Shape;
/**
* Get the type of this shape. You can use this to down cast to the concrete shape.
*
* @returns The shape type.
*/
GetType(): b2ShapeType;
/**
* 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: b2Transform, p: XY): boolean;
/**
* Cast a ray against a child shape.
*
* @param output The ray-cast results.
* @param input The ray-cast input parameters.
* @param transform The transform to be applied to the shape.
* @param childIndex The child shape index
*/
abstract RayCast(output: b2RayCastOutput, input: b2RayCastInput, transform: b2Transform, 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: b2AABB, xf: b2Transform, 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: b2MassData, density: number): void;
abstract SetupDistanceProxy(proxy: b2DistanceProxy, index: number): void;
abstract Draw(draw: b2Draw, color: b2Color): void;
}
//# sourceMappingURL=b2_shape.d.ts.map

@@ -21,12 +21,13 @@ "use strict";

exports.b2Shape = exports.b2ShapeType = exports.b2MassData = void 0;
// DEBUG: import { b2Assert } from "../common/b2_common";
const b2_math_1 = require("../common/b2_math");
/// This holds the mass data computed for a shape.
/**
* This holds the mass data computed for a shape.
*/
class b2MassData {
constructor() {
/// The mass of the shape, usually in kilograms.
/** The mass of the shape, usually in kilograms. */
this.mass = 0;
/// The position of the shape's centroid relative to the shape's origin.
/** The position of the shape's centroid relative to the shape's origin. */
this.center = new b2_math_1.b2Vec2();
/// The rotational inertia of the shape about the local origin.
/** The rotational inertia of the shape about the local origin. */
this.I = 0;

@@ -45,9 +46,13 @@ }

})(b2ShapeType = exports.b2ShapeType || (exports.b2ShapeType = {}));
/// A shape is used for collision detection. You can create a shape however you like.
/// Shapes used for simulation in b2World are created automatically when a b2Fixture
/// is created. Shapes may encapsulate a one or more child shapes.
/**
* A shape is used for collision detection. You can create a shape however you like.
* Shapes used for simulation in b2World are created automatically when a b2Fixture
* is created. Shapes may encapsulate a one or more child shapes.
*/
class b2Shape {
constructor(type, radius) {
/// Radius of a shape. For polygonal shapes this must be b2_polygonRadius. There is no support for
/// making rounded polygons.
/**
* Radius of a shape. For polygonal shapes this must be b2_polygonRadius. There is no support for
* making rounded polygons.
*/
this.m_radius = 0;

@@ -62,4 +67,7 @@ this.m_type = type;

}
/// Get the type of this shape. You can use this to down cast to the concrete shape.
/// @return the shape type.
/**
* Get the type of this shape. You can use this to down cast to the concrete shape.
*
* @returns The shape type.
*/
GetType() {

@@ -66,0 +74,0 @@ return this.m_type;

@@ -13,2 +13,5 @@ import { b2Sweep } from "../common/b2_math";

};
/**
* Input parameters for b2TimeOfImpact
*/
export declare class b2TOIInput {

@@ -28,2 +31,5 @@ readonly proxyA: b2DistanceProxy;

}
/**
* Output parameters for b2TimeOfImpact.
*/
export declare class b2TOIOutput {

@@ -30,0 +36,0 @@ state: b2TOIOutputState;

@@ -52,3 +52,5 @@ "use strict";

const b2TimeOfImpact_s_axisB = new b2_math_1.b2Vec2();
/// Input parameters for b2TimeOfImpact
/**
* Input parameters for b2TimeOfImpact
*/
class b2TOIInput {

@@ -64,3 +66,2 @@ constructor() {

exports.b2TOIInput = b2TOIInput;
/// Output parameters for b2TimeOfImpact.
var b2TOIOutputState;

@@ -74,2 +75,5 @@ (function (b2TOIOutputState) {

})(b2TOIOutputState = exports.b2TOIOutputState || (exports.b2TOIOutputState = {}));
/**
* Output parameters for b2TimeOfImpact.
*/
class b2TOIOutput {

@@ -224,3 +228,3 @@ constructor() {

default:
// DEBUG: b2Assert(false);
b2_common_1.b2Assert(false);
return 0;

@@ -297,7 +301,7 @@ }

const int32 N = 100;
float32 dx = 1.0f / N;
float32 dx = 1 / N;
float32 xs[N+1];
float32 fs[N+1];
float32 x = 0.0f;
float32 x = 0 ;

@@ -355,3 +359,3 @@ for (int32 i = 0; i <= N; ++i) {

if (s1 <= target + tolerance) {
// Victory! t1 should hold the TOI (could be 0.0).
// Victory! t1 should hold the TOI (could be 0).
output.state = b2TOIOutputState.e_touching;

@@ -368,3 +372,3 @@ output.t = t1;

// Use a mix of the secant rule and bisection.
let t = 0;
let t;
if (rootIterCount & 1) {

@@ -371,0 +375,0 @@ // Secant rule to improve convergence.

@@ -0,0 +0,0 @@ export declare type b2Augmentation<T extends {

@@ -0,0 +0,0 @@ "use strict";

@@ -6,21 +6,82 @@ export declare function b2Assert(condition: boolean, message?: string): asserts condition;

export declare const b2_epsilon_sq: number;
/**
* @file
* Global tuning constants based on meters-kilograms-seconds (MKS) units.
*/
/**
* The maximum number of contact points between two convex shapes. Do
* not change this value.
*/
export declare const b2_maxManifoldPoints = 2;
/**
* This is used to fatten AABBs in the dynamic tree. This allows proxies
* to move by a small amount without triggering a tree adjustment.
* This is in meters.
*/
export declare const b2_aabbExtension: number;
/**
* This is used to fatten AABBs in the dynamic tree. This is used to predict
* the future position based on the current displacement.
* This is a dimensionless multiplier.
*/
export declare const b2_aabbMultiplier = 4;
/**
* A small length used as a collision and constraint tolerance. Usually it is
* chosen to be numerically significant, but visually insignificant. In meters.
*/
export declare const b2_linearSlop: number;
/**
* A small angle used as a collision and constraint tolerance. Usually it is
* chosen to be numerically significant, but visually insignificant.
*/
export declare const b2_angularSlop: number;
/**
* The radius of the polygon/edge shape skin. This should not be modified. Making
* this smaller means polygons will have an insufficient buffer for continuous collision.
* Making it larger may create artifacts for vertex collision.
*/
export declare const b2_polygonRadius: number;
/** Maximum number of sub-steps per contact in continuous physics simulation. */
export declare const b2_maxSubSteps = 8;
/** Maximum number of contacts to be handled to solve a TOI impact. */
export declare const b2_maxTOIContacts = 32;
/**
* The maximum linear position correction used when solving constraints. This helps to
* prevent overshoot. Meters.
*/
export declare const b2_maxLinearCorrection: number;
/**
* The maximum angular position correction used when solving constraints. This helps to
* prevent overshoot.
*/
export declare const b2_maxAngularCorrection: number;
/**
* The maximum linear translation of a body per step. This limit is very large and is used
* to prevent numerical problems. You shouldn't need to adjust this. Meters.
*/
export declare const b2_maxTranslation: number;
export declare const b2_maxTranslationSquared: number;
/**
* The maximum angular velocity of a body. This limit is very large and is used
* to prevent numerical problems. You shouldn't need to adjust this.
*/
export declare const b2_maxRotation: number;
export declare const b2_maxRotationSquared: number;
/**
* This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
* that overlap is removed in one time step. However using values close to 1 often lead
* to overshoot.
*/
export declare const b2_baumgarte = 0.2;
export declare const b2_toiBaumgarte = 0.75;
/** The time that a body must be still before it will go to sleep. */
export declare const b2_timeToSleep = 0.5;
/** A body cannot sleep if its linear velocity is above this tolerance. */
export declare const b2_linearSleepTolerance: number;
/** A body cannot sleep if its angular velocity is above this tolerance. */
export declare const b2_angularSleepTolerance: number;
/**
* Current version.
* @see http://en.wikipedia.org/wiki/Software_versioning
*/
export declare const b2_version: {

@@ -32,2 +93,7 @@ major: number;

export declare function b2MakeNumberArray(length: number, init?: number): number[];
export declare function b2MakeBooleanArray(length: number, init?: boolean): boolean[];
export interface NoArgsConstructor<T> {
new (): T;
}
export declare function b2MakeArray<T>(length: number, Class: NoArgsConstructor<T>): T[];
//# sourceMappingURL=b2_common.d.ts.map

@@ -20,3 +20,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2MakeNumberArray = exports.b2_version = exports.b2_angularSleepTolerance = exports.b2_linearSleepTolerance = exports.b2_timeToSleep = exports.b2_toiBaumgarte = exports.b2_baumgarte = exports.b2_maxRotationSquared = exports.b2_maxRotation = exports.b2_maxTranslationSquared = exports.b2_maxTranslation = exports.b2_maxAngularCorrection = exports.b2_maxLinearCorrection = exports.b2_maxTOIContacts = exports.b2_maxSubSteps = exports.b2_polygonRadius = exports.b2_angularSlop = exports.b2_linearSlop = exports.b2_aabbMultiplier = exports.b2_aabbExtension = exports.b2_maxManifoldPoints = exports.b2_epsilon_sq = exports.b2_epsilon = exports.b2_maxFloat = exports.b2Verify = exports.b2Assert = void 0;
exports.b2MakeArray = exports.b2MakeBooleanArray = exports.b2MakeNumberArray = exports.b2_version = exports.b2_angularSleepTolerance = exports.b2_linearSleepTolerance = exports.b2_timeToSleep = exports.b2_toiBaumgarte = exports.b2_baumgarte = exports.b2_maxRotationSquared = exports.b2_maxRotation = exports.b2_maxTranslationSquared = exports.b2_maxTranslation = exports.b2_maxAngularCorrection = exports.b2_maxLinearCorrection = exports.b2_maxTOIContacts = exports.b2_maxSubSteps = exports.b2_polygonRadius = exports.b2_angularSlop = exports.b2_linearSlop = exports.b2_aabbMultiplier = exports.b2_aabbExtension = exports.b2_maxManifoldPoints = exports.b2_epsilon_sq = exports.b2_epsilon = exports.b2_maxFloat = exports.b2Verify = exports.b2Assert = void 0;
const b2_settings_1 = require("./b2_settings");

@@ -37,60 +37,85 @@ function b2Assert(condition, message) {

exports.b2_epsilon_sq = exports.b2_epsilon * exports.b2_epsilon;
/// @file
/// Global tuning constants based on meters-kilograms-seconds (MKS) units.
///
/**
* @file
* Global tuning constants based on meters-kilograms-seconds (MKS) units.
*/
// Collision
/// The maximum number of contact points between two convex shapes. Do
/// not change this value.
/**
* The maximum number of contact points between two convex shapes. Do
* not change this value.
*/
exports.b2_maxManifoldPoints = 2;
/// This is used to fatten AABBs in the dynamic tree. This allows proxies
/// to move by a small amount without triggering a tree adjustment.
/// This is in meters.
/**
* This is used to fatten AABBs in the dynamic tree. This allows proxies
* to move by a small amount without triggering a tree adjustment.
* This is in meters.
*/
exports.b2_aabbExtension = 0.1 * b2_settings_1.b2_lengthUnitsPerMeter;
/// This is used to fatten AABBs in the dynamic tree. This is used to predict
/// the future position based on the current displacement.
/// This is a dimensionless multiplier.
/**
* This is used to fatten AABBs in the dynamic tree. This is used to predict
* the future position based on the current displacement.
* This is a dimensionless multiplier.
*/
exports.b2_aabbMultiplier = 4;
/// A small length used as a collision and constraint tolerance. Usually it is
/// chosen to be numerically significant, but visually insignificant.
/**
* A small length used as a collision and constraint tolerance. Usually it is
* chosen to be numerically significant, but visually insignificant. In meters.
*/
exports.b2_linearSlop = 0.005 * b2_settings_1.b2_lengthUnitsPerMeter;
/// A small angle used as a collision and constraint tolerance. Usually it is
/// chosen to be numerically significant, but visually insignificant.
/**
* A small angle used as a collision and constraint tolerance. Usually it is
* chosen to be numerically significant, but visually insignificant.
*/
exports.b2_angularSlop = (2 / 180) * Math.PI;
/// The radius of the polygon/edge shape skin. This should not be modified. Making
/// this smaller means polygons will have an insufficient buffer for continuous collision.
/// Making it larger may create artifacts for vertex collision.
/**
* The radius of the polygon/edge shape skin. This should not be modified. Making
* this smaller means polygons will have an insufficient buffer for continuous collision.
* Making it larger may create artifacts for vertex collision.
*/
exports.b2_polygonRadius = 2 * exports.b2_linearSlop;
/// Maximum number of sub-steps per contact in continuous physics simulation.
/** Maximum number of sub-steps per contact in continuous physics simulation. */
exports.b2_maxSubSteps = 8;
// Dynamics
/// Maximum number of contacts to be handled to solve a TOI impact.
/** Maximum number of contacts to be handled to solve a TOI impact. */
exports.b2_maxTOIContacts = 32;
/// The maximum linear position correction used when solving constraints. This helps to
/// prevent overshoot. Meters.
/**
* The maximum linear position correction used when solving constraints. This helps to
* prevent overshoot. Meters.
*/
exports.b2_maxLinearCorrection = 0.2 * b2_settings_1.b2_lengthUnitsPerMeter;
/// The maximum angular position correction used when solving constraints. This helps to
/// prevent overshoot.
/**
* The maximum angular position correction used when solving constraints. This helps to
* prevent overshoot.
*/
exports.b2_maxAngularCorrection = (8 / 180) * Math.PI;
/// The maximum linear translation of a body per step. This limit is very large and is used
/// to prevent numerical problems. You shouldn't need to adjust this. Meters.
/**
* The maximum linear translation of a body per step. This limit is very large and is used
* to prevent numerical problems. You shouldn't need to adjust this. Meters.
*/
exports.b2_maxTranslation = 2 * b2_settings_1.b2_lengthUnitsPerMeter;
exports.b2_maxTranslationSquared = exports.b2_maxTranslation * exports.b2_maxTranslation;
/// The maximum angular velocity of a body. This limit is very large and is used
/// to prevent numerical problems. You shouldn't need to adjust this.
/**
* The maximum angular velocity of a body. This limit is very large and is used
* to prevent numerical problems. You shouldn't need to adjust this.
*/
exports.b2_maxRotation = 0.5 * Math.PI;
exports.b2_maxRotationSquared = exports.b2_maxRotation * exports.b2_maxRotation;
/// This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
/// that overlap is removed in one time step. However using values close to 1 often lead
/// to overshoot.
/**
* This scale factor controls how fast overlap is resolved. Ideally this would be 1 so
* that overlap is removed in one time step. However using values close to 1 often lead
* to overshoot.
*/
exports.b2_baumgarte = 0.2;
exports.b2_toiBaumgarte = 0.75;
// Sleep
/// The time that a body must be still before it will go to sleep.
/** The time that a body must be still before it will go to sleep. */
exports.b2_timeToSleep = 0.5;
/// A body cannot sleep if its linear velocity is above this tolerance.
/** A body cannot sleep if its linear velocity is above this tolerance. */
exports.b2_linearSleepTolerance = 0.01 * b2_settings_1.b2_lengthUnitsPerMeter;
/// A body cannot sleep if its angular velocity is above this tolerance.
/** A body cannot sleep if its angular velocity is above this tolerance. */
exports.b2_angularSleepTolerance = (2 / 180) * Math.PI;
/// Current version.
/// See http://en.wikipedia.org/wiki/Software_versioning
/**
* Current version.
* @see http://en.wikipedia.org/wiki/Software_versioning
*/
exports.b2_version = {

@@ -108,1 +133,15 @@ major: 2,

exports.b2MakeNumberArray = b2MakeNumberArray;
function b2MakeBooleanArray(length, init = false) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = init;
return result;
}
exports.b2MakeBooleanArray = b2MakeBooleanArray;
function b2MakeArray(length, Class) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new Class();
return result;
}
exports.b2MakeArray = b2MakeArray;

@@ -1,14 +0,5 @@

import { b2Color, b2Draw } from "./b2_draw";
import { b2Draw } from "./b2_draw";
import { b2Body } from "../dynamics/b2_body";
import { b2Fixture } from "../dynamics/b2_fixture";
import { b2World } from "../dynamics/b2_world";
import { b2PrismaticJoint } from "../dynamics/b2_prismatic_joint";
import { b2WheelJoint } from "../dynamics/b2_wheel_joint";
import { b2RevoluteJoint } from "../dynamics/b2_revolute_joint";
import { b2Joint } from "../dynamics/b2_joint";
import { b2PulleyJoint } from "../dynamics/b2_pulley_joint";
import { b2MouseJoint } from "../dynamics/b2_mouse_joint";
import { b2DistanceJoint } from "../dynamics/b2_distance_joint";
import { b2Rope } from "../rope/b2_rope";
export declare function GetShapeColor(b: b2Body): b2Color;
export declare function GetShapeColor(b: b2Body): import("./b2_draw").b2Color;
export declare function DrawShapes(draw: b2Draw, world: b2World): void;

@@ -19,11 +10,2 @@ export declare function DrawJoints(draw: b2Draw, world: b2World): void;

export declare function DrawCenterOfMasses(draw: b2Draw, world: b2World): void;
export declare function DrawShape(draw: b2Draw, fixture: b2Fixture, color: b2Color): void;
export declare function DrawWheelOrPrismaticJoint(draw: b2Draw, joint: b2PrismaticJoint | b2WheelJoint): void;
export declare function DrawRevoluteJoint(draw: b2Draw, joint: b2RevoluteJoint): void;
export declare function DrawMouseJoint(draw: b2Draw, joint: b2MouseJoint): void;
export declare function DrawPulleyJoint(draw: b2Draw, joint: b2PulleyJoint): void;
export declare function DrawDistanceJoint(draw: b2Draw, joint: b2DistanceJoint): void;
export declare function DrawJointFallback(draw: b2Draw, joint: b2Joint): void;
export declare function DrawJoint(draw: b2Draw, joint: b2Joint): void;
export declare function DrawRope(draw: b2Draw, rope: b2Rope): void;
//# sourceMappingURL=b2_draw_helper.d.ts.map
"use strict";
/* eslint-disable dot-notation */
/*

@@ -21,66 +20,31 @@ * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org

Object.defineProperty(exports, "__esModule", { value: true });
exports.DrawRope = exports.DrawJoint = exports.DrawJointFallback = exports.DrawDistanceJoint = exports.DrawPulleyJoint = exports.DrawMouseJoint = exports.DrawRevoluteJoint = exports.DrawWheelOrPrismaticJoint = exports.DrawShape = exports.DrawCenterOfMasses = exports.DrawAABBs = exports.DrawPairs = exports.DrawJoints = exports.DrawShapes = exports.GetShapeColor = void 0;
exports.DrawCenterOfMasses = exports.DrawAABBs = exports.DrawPairs = exports.DrawJoints = exports.DrawShapes = exports.GetShapeColor = void 0;
const b2_math_1 = require("./b2_math");
const b2_draw_1 = require("./b2_draw");
const b2_shape_1 = require("../collision/b2_shape");
const b2_body_1 = require("../dynamics/b2_body");
const b2_joint_1 = require("../dynamics/b2_joint");
const b2_common_1 = require("./b2_common");
const debugColors = {
badBody: new b2_draw_1.b2Color(1.0, 0.0, 0.0),
disabledBody: new b2_draw_1.b2Color(0.5, 0.5, 0.3),
staticBody: new b2_draw_1.b2Color(0.5, 0.9, 0.5),
kinematicBody: new b2_draw_1.b2Color(0.5, 0.5, 0.9),
sleepingBody: new b2_draw_1.b2Color(0.6, 0.6, 0.6),
body: new b2_draw_1.b2Color(0.9, 0.7, 0.7),
pair: new b2_draw_1.b2Color(0.3, 0.9, 0.9),
aabb: new b2_draw_1.b2Color(0.9, 0.3, 0.9),
joint1: new b2_draw_1.b2Color(0.7, 0.7, 0.7),
joint2: new b2_draw_1.b2Color(0.3, 0.9, 0.3),
joint3: new b2_draw_1.b2Color(0.9, 0.3, 0.3),
joint4: new b2_draw_1.b2Color(0.3, 0.3, 0.9),
joint5: new b2_draw_1.b2Color(0.4, 0.4, 0.4),
joint6: new b2_draw_1.b2Color(0.5, 0.8, 0.8),
joint7: new b2_draw_1.b2Color(0.0, 1, 0.0),
joint8: new b2_draw_1.b2Color(0.8, 0.8, 0.8),
rope: new b2_draw_1.b2Color(0.4, 0.5, 0.7),
ropePointG: new b2_draw_1.b2Color(0.1, 0.8, 0.1),
ropePointD: new b2_draw_1.b2Color(0.7, 0.2, 0.4),
};
const temp = {
cA: new b2_math_1.b2Vec2(),
cB: new b2_math_1.b2Vec2(),
vs: b2_math_1.b2Vec2.MakeArray(4),
vs: b2_common_1.b2MakeArray(4, b2_math_1.b2Vec2),
xf: new b2_math_1.b2Transform(),
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
axis: new b2_math_1.b2Vec2(),
lower: new b2_math_1.b2Vec2(),
upper: new b2_math_1.b2Vec2(),
perp: new b2_math_1.b2Vec2(),
p1: new b2_math_1.b2Vec2(),
p2: new b2_math_1.b2Vec2(),
rlo: new b2_math_1.b2Vec2(),
rhi: new b2_math_1.b2Vec2(),
r: new b2_math_1.b2Vec2(),
pRest: new b2_math_1.b2Vec2(),
};
function GetShapeColor(b) {
if (b.GetType() === b2_body_1.b2BodyType.b2_dynamicBody && b.m_mass === 0.0) {
if (b.GetType() === b2_body_1.b2BodyType.b2_dynamicBody && b.m_mass === 0) {
// Bad body
return debugColors.badBody;
return b2_draw_1.debugColors.badBody;
}
if (!b.IsEnabled()) {
return debugColors.disabledBody;
return b2_draw_1.debugColors.disabledBody;
}
if (b.GetType() === b2_body_1.b2BodyType.b2_staticBody) {
return debugColors.staticBody;
return b2_draw_1.debugColors.staticBody;
}
if (b.GetType() === b2_body_1.b2BodyType.b2_kinematicBody) {
return debugColors.kinematicBody;
return b2_draw_1.debugColors.kinematicBody;
}
if (!b.IsAwake()) {
return debugColors.sleepingBody;
return b2_draw_1.debugColors.sleepingBody;
}
return debugColors.body;
return b2_draw_1.debugColors.body;
}

@@ -93,3 +57,3 @@ exports.GetShapeColor = GetShapeColor;

for (let f = b.GetFixtureList(); f; f = f.m_next) {
DrawShape(draw, f, GetShapeColor(b));
f.GetShape().Draw(draw, GetShapeColor(b));
}

@@ -102,3 +66,3 @@ draw.PopTransform(xf);

for (let j = world.GetJointList(); j; j = j.m_next) {
DrawJoint(draw, j);
j.Draw(draw);
}

@@ -115,3 +79,3 @@ }

const cB = fixtureB.GetAABB(indexB).GetCenter(temp.cB);
draw.DrawSegment(cA, cB, debugColors.pair);
draw.DrawSegment(cA, cB, b2_draw_1.debugColors.pair);
}

@@ -134,3 +98,3 @@ }

vs[3].Set(aabb.lowerBound.x, aabb.upperBound.y);
draw.DrawPolygon(vs, 4, debugColors.aabb);
draw.DrawPolygon(vs, 4, b2_draw_1.debugColors.aabb);
}

@@ -150,180 +114,1 @@ }

exports.DrawCenterOfMasses = DrawCenterOfMasses;
function DrawShape(draw, fixture, color) {
const shape = fixture.GetShape();
switch (shape.m_type) {
case b2_shape_1.b2ShapeType.e_circle: {
const circle = shape;
const center = circle.m_p;
const radius = circle.m_radius;
const axis = b2_math_1.b2Vec2.UNITX;
draw.DrawSolidCircle(center, radius, axis, color);
break;
}
case b2_shape_1.b2ShapeType.e_edge: {
const edge = shape;
const v1 = edge.m_vertex1;
const v2 = edge.m_vertex2;
draw.DrawSegment(v1, v2, color);
if (edge.m_oneSided === false) {
draw.DrawPoint(v1, 4.0, color);
draw.DrawPoint(v2, 4.0, color);
}
break;
}
case b2_shape_1.b2ShapeType.e_chain: {
const chain = shape;
const vertices = chain.m_vertices;
let v1 = vertices[0];
for (let i = 1; i < vertices.length; ++i) {
const v2 = vertices[i];
draw.DrawSegment(v1, v2, color);
v1 = v2;
}
break;
}
case b2_shape_1.b2ShapeType.e_polygon: {
const poly = shape;
const vertexCount = poly.m_count;
const vertices = poly.m_vertices;
draw.DrawSolidPolygon(vertices, vertexCount, color);
break;
}
}
}
exports.DrawShape = DrawShape;
function DrawWheelOrPrismaticJoint(draw, joint) {
const { p1, p2, pA, pB, axis } = temp;
const xfA = joint.m_bodyA.GetTransform();
const xfB = joint.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, joint.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, joint.m_localAnchorB, pB);
b2_math_1.b2Rot.MultiplyVec2(xfA.q, joint.m_localXAxisA, axis);
draw.DrawSegment(pA, pB, debugColors.joint5);
if (joint.m_enableLimit) {
const { lower, upper, perp } = temp;
b2_math_1.b2Vec2.AddScaled(pA, joint.m_lowerTranslation, axis, lower);
b2_math_1.b2Vec2.AddScaled(pA, joint.m_upperTranslation, axis, upper);
b2_math_1.b2Rot.MultiplyVec2(xfA.q, joint.m_localYAxisA, perp);
draw.DrawSegment(lower, upper, debugColors.joint1);
draw.DrawSegment(b2_math_1.b2Vec2.SubtractScaled(lower, 0.5, perp, p1), b2_math_1.b2Vec2.AddScaled(lower, 0.5, perp, p2), debugColors.joint2);
draw.DrawSegment(b2_math_1.b2Vec2.SubtractScaled(upper, 0.5, perp, p1), b2_math_1.b2Vec2.AddScaled(upper, 0.5, perp, p2), debugColors.joint3);
}
else {
draw.DrawSegment(b2_math_1.b2Vec2.Subtract(pA, axis, p1), b2_math_1.b2Vec2.Add(pA, axis, p2), debugColors.joint1);
}
draw.DrawPoint(pA, 5.0, debugColors.joint1);
draw.DrawPoint(pB, 5.0, debugColors.joint4);
}
exports.DrawWheelOrPrismaticJoint = DrawWheelOrPrismaticJoint;
function DrawRevoluteJoint(draw, joint) {
const { p2, r, pA, pB } = temp;
const xfA = joint.m_bodyA.GetTransform();
const xfB = joint.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, joint.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, joint.m_localAnchorB, pB);
draw.DrawPoint(pA, 5.0, debugColors.joint4);
draw.DrawPoint(pB, 5.0, debugColors.joint5);
const aA = joint.m_bodyA.GetAngle();
const aB = joint.m_bodyB.GetAngle();
const angle = aB - aA - joint.m_referenceAngle;
const L = 0.5;
r.Set(Math.cos(angle), Math.sin(angle)).Scale(L);
draw.DrawSegment(pB, b2_math_1.b2Vec2.Add(pB, r, p2), debugColors.joint1);
draw.DrawCircle(pB, L, debugColors.joint1);
if (joint.m_enableLimit) {
const { rlo, rhi } = temp;
rlo.Set(Math.cos(joint.m_lowerAngle), Math.sin(joint.m_lowerAngle)).Scale(L);
rhi.Set(Math.cos(joint.m_upperAngle), Math.sin(joint.m_upperAngle)).Scale(L);
draw.DrawSegment(pB, b2_math_1.b2Vec2.Add(pB, rlo, p2), debugColors.joint2);
draw.DrawSegment(pB, b2_math_1.b2Vec2.Add(pB, rhi, p2), debugColors.joint3);
}
draw.DrawSegment(xfA.p, pA, debugColors.joint6);
draw.DrawSegment(pA, pB, debugColors.joint6);
draw.DrawSegment(xfB.p, pB, debugColors.joint6);
}
exports.DrawRevoluteJoint = DrawRevoluteJoint;
function DrawMouseJoint(draw, joint) {
const p1 = joint.GetAnchorA(temp.pA);
const p2 = joint.GetAnchorB(temp.pB);
draw.DrawPoint(p1, 4, debugColors.joint7);
draw.DrawPoint(p2, 4, debugColors.joint7);
draw.DrawSegment(p1, p2, debugColors.joint8);
}
exports.DrawMouseJoint = DrawMouseJoint;
function DrawPulleyJoint(draw, joint) {
const p1 = joint.GetAnchorA(temp.pA);
const p2 = joint.GetAnchorB(temp.pB);
const s1 = joint.GetGroundAnchorA();
const s2 = joint.GetGroundAnchorB();
draw.DrawSegment(s1, p1, debugColors.joint6);
draw.DrawSegment(s2, p2, debugColors.joint6);
draw.DrawSegment(s1, s2, debugColors.joint6);
}
exports.DrawPulleyJoint = DrawPulleyJoint;
function DrawDistanceJoint(draw, joint) {
const { pA, pB, axis, pRest } = temp;
const xfA = joint.m_bodyA.GetTransform();
const xfB = joint.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, joint.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, joint.m_localAnchorB, pB);
b2_math_1.b2Vec2.Subtract(pB, pA, axis);
axis.Normalize();
draw.DrawSegment(pA, pB, debugColors.joint5);
b2_math_1.b2Vec2.AddScaled(pA, joint.m_length, axis, pRest);
draw.DrawPoint(pRest, 8.0, debugColors.joint1);
if (joint.m_minLength !== joint.m_maxLength) {
if (joint.m_minLength > b2_common_1.b2_linearSlop) {
const pMin = b2_math_1.b2Vec2.AddScaled(pA, joint.m_minLength, axis, temp.p1);
draw.DrawPoint(pMin, 4.0, debugColors.joint2);
}
if (joint.m_maxLength < b2_common_1.b2_maxFloat) {
const pMax = b2_math_1.b2Vec2.AddScaled(pA, joint.m_maxLength, axis, temp.p1);
draw.DrawPoint(pMax, 4.0, debugColors.joint3);
}
}
}
exports.DrawDistanceJoint = DrawDistanceJoint;
function DrawJointFallback(draw, joint) {
const x1 = joint.m_bodyA.GetTransform().p;
const x2 = joint.m_bodyB.GetTransform().p;
const p1 = joint.GetAnchorA(temp.pA);
const p2 = joint.GetAnchorB(temp.pB);
draw.DrawSegment(x1, p1, debugColors.joint6);
draw.DrawSegment(p1, p2, debugColors.joint6);
draw.DrawSegment(x2, p2, debugColors.joint6);
}
exports.DrawJointFallback = DrawJointFallback;
function DrawJoint(draw, joint) {
switch (joint.m_type) {
case b2_joint_1.b2JointType.e_prismaticJoint:
case b2_joint_1.b2JointType.e_wheelJoint:
DrawWheelOrPrismaticJoint(draw, joint);
break;
case b2_joint_1.b2JointType.e_revoluteJoint:
DrawRevoluteJoint(draw, joint);
break;
case b2_joint_1.b2JointType.e_distanceJoint:
DrawDistanceJoint(draw, joint);
break;
case b2_joint_1.b2JointType.e_pulleyJoint:
DrawPulleyJoint(draw, joint);
break;
case b2_joint_1.b2JointType.e_mouseJoint:
DrawMouseJoint(draw, joint);
break;
default:
DrawJointFallback(draw, joint);
break;
}
}
exports.DrawJoint = DrawJoint;
function DrawRope(draw, rope) {
for (let i = 0; i < rope["m_count"] - 1; ++i) {
draw.DrawSegment(rope["m_ps"][i], rope["m_ps"][i + 1], debugColors.rope);
const pc = rope["m_invMasses"][i] > 0.0 ? debugColors.ropePointD : debugColors.ropePointG;
draw.DrawPoint(rope["m_ps"][i], 5.0, pc);
}
const pc = rope["m_invMasses"][rope["m_count"] - 1] > 0.0 ? debugColors.ropePointD : debugColors.ropePointG;
draw.DrawPoint(rope["m_ps"][rope["m_count"] - 1], 5.0, pc);
}
exports.DrawRope = DrawRope;

@@ -10,2 +10,5 @@ import { b2Transform, XY } from "./b2_math";

}
/**
* Color for debug drawing. Each value has the range [0,1].
*/
export declare class b2Color implements RGBA {

@@ -40,2 +43,6 @@ static readonly ZERO: Readonly<RGBA>;

}
/**
* Implement and register this class with a b2World to provide debug drawing of physics
* entities in your game.
*/
export interface b2Draw {

@@ -52,2 +59,23 @@ PushTransform(xf: b2Transform): void;

}
export declare const debugColors: {
badBody: b2Color;
disabledBody: b2Color;
staticBody: b2Color;
kinematicBody: b2Color;
sleepingBody: b2Color;
body: b2Color;
pair: b2Color;
aabb: b2Color;
joint1: b2Color;
joint2: b2Color;
joint3: b2Color;
joint4: b2Color;
joint5: b2Color;
joint6: b2Color;
joint7: b2Color;
joint8: b2Color;
rope: b2Color;
ropePointG: b2Color;
ropePointD: b2Color;
};
//# sourceMappingURL=b2_draw.d.ts.map

@@ -20,6 +20,8 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2Color = void 0;
/// Color for debug drawing. Each value has the range [0,1].
exports.debugColors = exports.b2Color = void 0;
/**
* Color for debug drawing. Each value has the range [0,1].
*/
class b2Color {
constructor(r = 0.5, g = 0.5, b = 0.5, a = 1.0) {
constructor(r = 0.5, g = 0.5, b = 0.5, a = 1) {
this.r = r;

@@ -31,3 +33,3 @@ this.g = g;

Clone() {
return new b2Color().Copy(this);
return new b2Color(this.r, this.g, this.b, this.a);
}

@@ -140,1 +142,22 @@ Copy(other) {

b2Color.BLACK = new b2Color(0, 0, 0);
exports.debugColors = {
badBody: new b2Color(1, 0, 0),
disabledBody: new b2Color(0.5, 0.5, 0.3),
staticBody: new b2Color(0.5, 0.9, 0.5),
kinematicBody: new b2Color(0.5, 0.5, 0.9),
sleepingBody: new b2Color(0.6, 0.6, 0.6),
body: new b2Color(0.9, 0.7, 0.7),
pair: new b2Color(0.3, 0.9, 0.9),
aabb: new b2Color(0.9, 0.3, 0.9),
joint1: new b2Color(0.7, 0.7, 0.7),
joint2: new b2Color(0.3, 0.9, 0.3),
joint3: new b2Color(0.9, 0.3, 0.3),
joint4: new b2Color(0.3, 0.3, 0.9),
joint5: new b2Color(0.4, 0.4, 0.4),
joint6: new b2Color(0.5, 0.8, 0.8),
joint7: new b2Color(0, 1, 0),
joint8: new b2Color(0.8, 0.8, 0.8),
rope: new b2Color(0.4, 0.5, 0.7),
ropePointG: new b2Color(0.1, 0.8, 0.1),
ropePointD: new b2Color(0.7, 0.2, 0.4),
};

@@ -7,6 +7,14 @@ export declare const b2_pi_over_180: number;

export declare function b2RadToDeg(radians: number): number;
/**
* "Next Largest Power of 2
* Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
* that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
* the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
* largest power of 2. For a 32-bit value:"
*/
export declare function b2NextPowerOfTwo(x: number): number;
export declare function b2IsPowerOfTwo(x: number): boolean;
export declare function b2Random(): number;
export declare function b2RandomRange(lo: number, hi: number): number;
export declare function b2RandomFloat(lo: number, hi: number): number;
export declare function b2RandomInt(lo: number, hi: number): number;
export interface XY {

@@ -16,2 +24,5 @@ x: number;

}
/**
* A 2D column vector.
*/
export declare class b2Vec2 implements XY {

@@ -29,25 +40,70 @@ static readonly ZERO: Readonly<XY>;

Clone(): b2Vec2;
/**
* Set this vector to all zeros.
*/
SetZero(): this;
/**
* Set this vector to some specified coordinates.
*/
Set(x: number, y: number): this;
Copy(other: XY): this;
/**
* Add a vector to this vector.
*/
Add(v: XY): this;
/**
* Add a vector to this vector.
*/
AddXY(x: number, y: number): this;
/**
* Subtract a vector from this vector.
*/
Subtract(v: XY): this;
/**
* Subtract a vector from this vector.
*/
SubtractXY(x: number, y: number): this;
/**
* Multiply this vector by a scalar.
*/
Scale(s: number): this;
AddScaled(s: number, v: XY): this;
SubtractScaled(s: number, v: XY): this;
/**
* Perform the dot product on two vectors.
*/
Dot(v: XY): number;
/**
* Perform the cross product on two vectors. In 2D this produces a scalar.
*/
Cross(v: XY): number;
/**
* Get the length of this vector (the norm).
*/
Length(): number;
/**
* Get the length squared. For performance, use this instead of
* b2Vec2::Length (if possible).
*/
LengthSquared(): number;
/**
* Convert this vector into a unit vector. Returns the length.
*/
Normalize(): number;
Rotate(radians: number): this;
RotateCosSin(c: number, s: number): this;
/**
* Does this vector contain finite coordinates?
*/
IsValid(): boolean;
Abs(): this;
GetAbs<T extends XY>(out: T): T;
/**
* Negate this vector.
*/
Negate(): this;
/**
* Skew this vector such that dot(skew_vec, other) == cross(vec, other)
*/
Skew(): this;
static MakeArray(length: number): b2Vec2[];
static Min<T extends XY>(a: XY, b: XY, out: T): T;

@@ -59,7 +115,21 @@ static Max<T extends XY>(a: XY, b: XY, out: T): T;

static Cross(a: XY, b: XY): number;
/**
* Perform the cross product on a vector and a scalar. In 2D this produces
* a vector.
*/
static CrossVec2Scalar<T extends XY>(v: XY, s: number, out: T): T;
static CrossVec2One<T extends XY>(v: XY, out: T): T;
/**
* Perform the cross product on a scalar and a vector. In 2D this produces
* a vector.
*/
static CrossScalarVec2<T extends XY>(s: number, v: XY, out: T): T;
static CrossOneVec2<T extends XY>(v: XY, out: T): T;
/**
* Add two vectors component-wise.
*/
static Add<T extends XY>(a: XY, b: XY, out: T): T;
/**
* Subtract two vectors component-wise.
*/
static Subtract<T extends XY>(a: XY, b: XY, out: T): T;

@@ -75,3 +145,11 @@ static Scale<T extends XY>(s: number, v: XY, out: T): T;

static DistanceSquared(a: XY, b: XY): number;
/**
* Negate a vector.
*/
static Negate<T extends XY>(v: XY, out: T): T;
static Normalize<T extends XY>(v: XY, out: T): T;
/**
* Skew a vector such that dot(skew_vec, other) == cross(vec, other)
*/
static Skew<T extends XY>(v: XY, out: T): T;
}

@@ -81,2 +159,5 @@ export interface XYZ extends XY {

}
/**
* A 2D column vector with 3 elements.
*/
export declare class b2Vec3 implements XYZ {

@@ -90,14 +171,47 @@ static readonly ZERO: Readonly<XYZ>;

Clone(): b2Vec3;
/**
* Set this vector to all zeros.
*/
SetZero(): this;
/**
* Set this vector to some specified coordinates.
*/
Set(x: number, y: number, z: number): this;
Copy(other: XYZ): this;
/**
* Negate this vector.
*/
Negate(): this;
/**
* Add a vector to this vector.
*/
Add(v: XYZ): this;
/**
* Add a vector to this vector.
*/
AddXYZ(x: number, y: number, z: number): this;
/**
* Subtract a vector from this vector.
*/
Subtract(v: XYZ): this;
/**
* Subtract a vector from this vector.
*/
SubtractXYZ(x: number, y: number, z: number): this;
/**
* Multiply this vector by a scalar.
*/
Scale(s: number): this;
/**
* Perform the dot product on two vectors.
*/
static Dot(a: XYZ, b: XYZ): number;
/**
* Perform the cross product on two vectors.
*/
static Cross<T extends XYZ>(a: XYZ, b: XYZ, out: T): T;
}
/**
* A 2-by-2 matrix. Stored in column-major order.
*/
export declare class b2Mat22 {

@@ -108,12 +222,34 @@ static readonly IDENTITY: Readonly<b2Mat22>;

Clone(): b2Mat22;
/**
* Construct a matrix using columns.
*/
static FromColumns(c1: XY, c2: XY): b2Mat22;
/**
* Construct a matrix using scalars.
*/
static FromScalars(r1c1: number, r1c2: number, r2c1: number, r2c2: number): b2Mat22;
static FromAngle(radians: number): b2Mat22;
/**
* Set this matrix using scalars.
*/
SetScalars(r1c1: number, r1c2: number, r2c1: number, r2c2: number): this;
/**
* Initialize this matrix using columns.
*/
SetColumns(c1: XY, c2: XY): this;
SetAngle(radians: number): this;
Copy(other: b2Mat22): this;
/**
* Set this to the identity matrix.
*/
SetIdentity(): this;
/**
* Set this matrix to all zeros.
*/
SetZero(): this;
GetAngle(): number;
/**
* Solve A * x = b, where b is a column vector. This is more efficient
* than computing the inverse in one-shot cases.
*/
Solve<T extends XY>(b_x: number, b_y: number, out: T): T;

@@ -126,3 +262,11 @@ Abs(): this;

GetAbs(out: b2Mat22): b2Mat22;
/**
* Multiply a matrix times a vector. If a rotation matrix is provided,
* then this transforms the vector from one frame to another.
*/
static MultiplyVec2<T extends XY>(M: b2Mat22, v: XY, out: T): T;
/**
* Multiply a matrix transpose times a vector. If a rotation matrix is provided,
* then this transforms the vector from one frame to another (inverse transform).
*/
static TransposeMultiplyVec2<T extends XY>(M: b2Mat22, v: XY, out: T): T;

@@ -133,2 +277,5 @@ static Add(A: b2Mat22, B: b2Mat22, out: b2Mat22): b2Mat22;

}
/**
* A 3-by-3 matrix. Stored in column-major order.
*/
export declare class b2Mat33 {

@@ -140,31 +287,99 @@ static readonly IDENTITY: Readonly<b2Mat33>;

Clone(): b2Mat33;
/**
* Set this matrix using columns.
*/
SetColumns(c1: XYZ, c2: XYZ, c3: XYZ): this;
Copy(other: b2Mat33): this;
SetIdentity(): this;
/**
* Set this matrix to all zeros.
*/
SetZero(): this;
Add(M: b2Mat33): this;
/**
* Solve A * x = b, where b is a column vector. This is more efficient
* than computing the inverse in one-shot cases.
*/
Solve33<T extends XYZ>(b_x: number, b_y: number, b_z: number, out: T): T;
/**
* Solve A * x = b, where b is a column vector. This is more efficient
* than computing the inverse in one-shot cases. Solve only the upper
* 2-by-2 matrix equation.
*/
Solve22<T extends XY>(b_x: number, b_y: number, out: T): T;
/**
* Get the inverse of this matrix as a 2-by-2.
* Returns the zero matrix if singular.
*/
GetInverse22(M: b2Mat33): void;
/**
* Get the symmetric inverse of this matrix as a 3-by-3.
* Returns the zero matrix if singular.
*/
GetSymInverse33(M: b2Mat33): void;
/**
* Multiply a matrix times a vector.
*/
static MultiplyVec3<T extends XYZ>(A: b2Mat33, v: XYZ, out: T): T;
/**
* Multiply a matrix times a vector.
*/
static MultiplyVec2<T extends XY>(A: b2Mat33, v: XY, out: T): T;
}
/**
* Rotation
*/
export declare class b2Rot {
static readonly IDENTITY: Readonly<b2Rot>;
/** Sine */
s: number;
/** Cosine */
c: number;
/**
* Initialize from an angle in radians
*/
constructor(angle?: number);
Clone(): b2Rot;
Copy(other: b2Rot): this;
/**
* Set using an angle in radians.
*/
Set(angle: number): this;
/**
* Set to the identity rotation
*/
SetIdentity(): this;
/**
* Get the angle in radians
*/
GetAngle(): number;
/**
* Get the x-axis
*/
GetXAxis<T extends XY>(out: T): T;
/**
* Get the u-axis
*/
GetYAxis<T extends XY>(out: T): T;
/**
* Multiply two rotations: q * r
*/
static Multiply(q: b2Rot, r: b2Rot, out: b2Rot): b2Rot;
/**
* Transpose multiply two rotations: qT * r
*/
static TransposeMultiply(q: b2Rot, r: b2Rot, out: b2Rot): b2Rot;
/**
* Rotate a vector
*/
static MultiplyVec2<T extends XY>(q: b2Rot, v: XY, out: T): T;
/**
* Inverse rotate a vector
*/
static TransposeMultiplyVec2<T extends XY>(q: b2Rot, v: XY, out: T): T;
}
/**
* A transform contains translation and rotation. It is used to represent
* the position and orientation of rigid frames.
*/
export declare class b2Transform {

@@ -176,4 +391,13 @@ static readonly IDENTITY: Readonly<b2Transform>;

Copy(other: b2Transform): this;
/**
* Set this to the identity transform.
*/
SetIdentity(): this;
/**
* Set this based on the position and rotation.
*/
SetPositionRotation(position: XY, q: Readonly<b2Rot>): this;
/**
* Set this based on the position and angle.
*/
SetPositionAngle(pos: XY, a: number): this;

@@ -192,15 +416,45 @@ SetPosition(position: XY): this;

}
/**
* This describes the motion of a body/shape for TOI computation.
* Shapes are defined with respect to the body origin, which may
* no coincide with the center of mass. However, to support dynamics
* we must interpolate the center of mass position.
*/
export declare class b2Sweep {
/** Local center of mass position */
readonly localCenter: b2Vec2;
/** Center world position at time 0 */
readonly c0: b2Vec2;
/** Center world position at time 1 */
readonly c: b2Vec2;
/** World angle at time 0 */
a0: number;
/** World angle at time 1 */
a: number;
/**
* Fraction of the current time step in the range [0,1]
* c0 and a0 are the positions at alpha0.
*/
alpha0: number;
Clone(): b2Sweep;
Copy(other: b2Sweep): this;
/**
* Get the interpolated transform at a specific time.
*
* @param transform The output transform
* @param beta Is a factor in [0,1], where 0 indicates alpha0.
* @see https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
*/
GetTransform(xf: b2Transform, beta: number): b2Transform;
/**
* Advance the sweep forward, yielding a new initial state.
*
* @param alpha The new initial time.
*/
Advance(alpha: number): void;
/**
* Normalize an angle in radians to be between -pi and pi
*/
Normalize(): void;
}
//# sourceMappingURL=b2_math.d.ts.map

@@ -20,3 +20,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2Sweep = exports.b2Transform = exports.b2Rot = exports.b2Mat33 = exports.b2Mat22 = exports.b2Vec3 = exports.b2Vec2 = exports.b2RandomRange = exports.b2Random = exports.b2IsPowerOfTwo = exports.b2NextPowerOfTwo = exports.b2RadToDeg = exports.b2DegToRad = exports.b2Clamp = exports.b2_two_pi = exports.b2_180_over_pi = exports.b2_pi_over_180 = void 0;
exports.b2Sweep = exports.b2Transform = exports.b2Rot = exports.b2Mat33 = exports.b2Mat22 = exports.b2Vec3 = exports.b2Vec2 = exports.b2RandomInt = exports.b2RandomFloat = exports.b2Random = exports.b2IsPowerOfTwo = exports.b2NextPowerOfTwo = exports.b2RadToDeg = exports.b2DegToRad = exports.b2Clamp = exports.b2_two_pi = exports.b2_180_over_pi = exports.b2_pi_over_180 = void 0;
// DEBUG: import { b2Assert } from "./b2_common";

@@ -41,7 +41,9 @@ const b2_common_1 = require("./b2_common");

exports.b2RadToDeg = b2RadToDeg;
/// "Next Largest Power of 2
/// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
/// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
/// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
/// largest power of 2. For a 32-bit value:"
/**
* "Next Largest Power of 2
* Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm
* that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with
* the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next
* largest power of 2. For a 32-bit value:"
*/
function b2NextPowerOfTwo(x) {

@@ -64,7 +66,13 @@ x |= x >> 1;

exports.b2Random = b2Random;
function b2RandomRange(lo, hi) {
function b2RandomFloat(lo, hi) {
return (hi - lo) * Math.random() + lo;
}
exports.b2RandomRange = b2RandomRange;
/// A 2D column vector.
exports.b2RandomFloat = b2RandomFloat;
function b2RandomInt(lo, hi) {
return Math.round((hi - lo) * Math.random() + lo);
}
exports.b2RandomInt = b2RandomInt;
/**
* A 2D column vector.
*/
class b2Vec2 {

@@ -78,3 +86,5 @@ constructor(x = 0, y = 0) {

}
/// Set this vector to all zeros.
/**
* Set this vector to all zeros.
*/
SetZero() {

@@ -85,3 +95,5 @@ this.x = 0;

}
/// Set this vector to some specified coordinates.
/**
* Set this vector to some specified coordinates.
*/
Set(x, y) {

@@ -97,3 +109,5 @@ this.x = x;

}
/// Add a vector to this vector.
/**
* Add a vector to this vector.
*/
Add(v) {

@@ -104,3 +118,5 @@ this.x += v.x;

}
/// Add a vector to this vector.
/**
* Add a vector to this vector.
*/
AddXY(x, y) {

@@ -111,3 +127,5 @@ this.x += x;

}
/// Subtract a vector from this vector.
/**
* Subtract a vector from this vector.
*/
Subtract(v) {

@@ -118,3 +136,5 @@ this.x -= v.x;

}
/// Subtract a vector from this vector.
/**
* Subtract a vector from this vector.
*/
SubtractXY(x, y) {

@@ -125,3 +145,5 @@ this.x -= x;

}
/// Multiply this vector by a scalar.
/**
* Multiply this vector by a scalar.
*/
Scale(s) {

@@ -142,11 +164,17 @@ this.x *= s;

}
/// Perform the dot product on two vectors.
/**
* Perform the dot product on two vectors.
*/
Dot(v) {
return this.x * v.x + this.y * v.y;
}
/// Perform the cross product on two vectors. In 2D this produces a scalar.
/**
* Perform the cross product on two vectors. In 2D this produces a scalar.
*/
Cross(v) {
return this.x * v.y - this.y * v.x;
}
/// Get the length of this vector (the norm).
/**
* Get the length of this vector (the norm).
*/
Length() {

@@ -156,4 +184,6 @@ const { x, y } = this;

}
/// Get the length squared. For performance, use this instead of
/// b2Vec2::Length (if possible).
/**
* Get the length squared. For performance, use this instead of
* b2Vec2::Length (if possible).
*/
LengthSquared() {

@@ -163,3 +193,5 @@ const { x, y } = this;

}
/// Convert this vector into a unit vector. Returns the length.
/**
* Convert this vector into a unit vector. Returns the length.
*/
Normalize() {

@@ -189,3 +221,5 @@ const length = this.Length();

}
/// Does this vector contain finite coordinates?
/**
* Does this vector contain finite coordinates?
*/
IsValid() {

@@ -204,3 +238,5 @@ return Number.isFinite(this.x) && Number.isFinite(this.y);

}
/// Negate this vector.
/**
* Negate this vector.
*/
Negate() {

@@ -211,3 +247,5 @@ this.x = -this.x;

}
/// Skew this vector such that dot(skew_vec, other) == cross(vec, other)
/**
* Skew this vector such that dot(skew_vec, other) == cross(vec, other)
*/
Skew() {

@@ -219,8 +257,2 @@ const { x } = this;

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2Vec2();
return result;
}
static Min(a, b, out) {

@@ -256,4 +288,6 @@ out.x = Math.min(a.x, b.x);

}
/// Perform the cross product on a vector and a scalar. In 2D this produces
/// a vector.
/**
* Perform the cross product on a vector and a scalar. In 2D this produces
* a vector.
*/
static CrossVec2Scalar(v, s, out) {

@@ -271,4 +305,6 @@ const v_x = v.x;

}
/// Perform the cross product on a scalar and a vector. In 2D this produces
/// a vector.
/**
* Perform the cross product on a scalar and a vector. In 2D this produces
* a vector.
*/
static CrossScalarVec2(s, v, out) {

@@ -286,3 +322,5 @@ const v_x = v.x;

}
/// Add two vectors component-wise.
/**
* Add two vectors component-wise.
*/
static Add(a, b, out) {

@@ -293,3 +331,5 @@ out.x = a.x + b.x;

}
/// Subtract two vectors component-wise.
/**
* Subtract two vectors component-wise.
*/
static Subtract(a, b, out) {

@@ -340,3 +380,5 @@ out.x = a.x - b.x;

}
/// Negate a vector.
/**
* Negate a vector.
*/
static Negate(v, out) {

@@ -347,2 +389,24 @@ out.x = -v.x;

}
static Normalize(v, out) {
const length_sq = v.x ** 2 + v.y ** 2;
if (length_sq >= b2_common_1.b2_epsilon_sq) {
const inv_length = 1 / Math.sqrt(length_sq);
out.x = inv_length * v.x;
out.y = inv_length * v.y;
}
else {
out.x = 0;
out.y = 0;
}
return out;
}
/**
* Skew a vector such that dot(skew_vec, other) == cross(vec, other)
*/
static Skew(v, out) {
const { x } = v;
out.x = -v.y;
out.y = x;
return out;
}
}

@@ -357,3 +421,5 @@ exports.b2Vec2 = b2Vec2;

b2Vec2.s_t3 = new b2Vec2();
/// A 2D column vector with 3 elements.
/**
* A 2D column vector with 3 elements.
*/
class b2Vec3 {

@@ -368,3 +434,5 @@ constructor(x = 0, y = 0, z = 0) {

}
/// Set this vector to all zeros.
/**
* Set this vector to all zeros.
*/
SetZero() {

@@ -376,3 +444,5 @@ this.x = 0;

}
/// Set this vector to some specified coordinates.
/**
* Set this vector to some specified coordinates.
*/
Set(x, y, z) {

@@ -390,3 +460,5 @@ this.x = x;

}
/// Negate this vector.
/**
* Negate this vector.
*/
Negate() {

@@ -398,3 +470,5 @@ this.x = -this.x;

}
/// Add a vector to this vector.
/**
* Add a vector to this vector.
*/
Add(v) {

@@ -406,3 +480,5 @@ this.x += v.x;

}
/// Add a vector to this vector.
/**
* Add a vector to this vector.
*/
AddXYZ(x, y, z) {

@@ -414,3 +490,5 @@ this.x += x;

}
/// Subtract a vector from this vector.
/**
* Subtract a vector from this vector.
*/
Subtract(v) {

@@ -422,3 +500,5 @@ this.x -= v.x;

}
/// Subtract a vector from this vector.
/**
* Subtract a vector from this vector.
*/
SubtractXYZ(x, y, z) {

@@ -430,3 +510,5 @@ this.x -= x;

}
/// Multiply this vector by a scalar.
/**
* Multiply this vector by a scalar.
*/
Scale(s) {

@@ -438,7 +520,11 @@ this.x *= s;

}
/// Perform the dot product on two vectors.
/**
* Perform the dot product on two vectors.
*/
static Dot(a, b) {
return a.x * b.x + a.y * b.y + a.z * b.z;
}
/// Perform the cross product on two vectors.
/**
* Perform the cross product on two vectors.
*/
static Cross(a, b, out) {

@@ -460,3 +546,5 @@ const a_x = a.x;

b2Vec3.s_t0 = new b2Vec3();
/// A 2-by-2 matrix. Stored in column-major order.
/**
* A 2-by-2 matrix. Stored in column-major order.
*/
class b2Mat22 {

@@ -470,7 +558,11 @@ constructor() {

}
/// Construct a matrix using columns.
/**
* Construct a matrix using columns.
*/
static FromColumns(c1, c2) {
return new b2Mat22().SetColumns(c1, c2);
}
/// Construct a matrix using scalars.
/**
* Construct a matrix using scalars.
*/
static FromScalars(r1c1, r1c2, r2c1, r2c2) {

@@ -482,3 +574,5 @@ return new b2Mat22().SetScalars(r1c1, r1c2, r2c1, r2c2);

}
/// Set this matrix using scalars.
/**
* Set this matrix using scalars.
*/
SetScalars(r1c1, r1c2, r2c1, r2c2) {

@@ -489,3 +583,5 @@ this.ex.Set(r1c1, r2c1);

}
/// Initialize this matrix using columns.
/**
* Initialize this matrix using columns.
*/
SetColumns(c1, c2) {

@@ -508,3 +604,5 @@ this.ex.Copy(c1);

}
/// Set this to the identity matrix.
/**
* Set this to the identity matrix.
*/
SetIdentity() {

@@ -515,3 +613,5 @@ this.ex.Set(1, 0);

}
/// Set this matrix to all zeros.
/**
* Set this matrix to all zeros.
*/
SetZero() {

@@ -525,4 +625,6 @@ this.ex.SetZero();

}
/// Solve A * x = b, where b is a column vector. This is more efficient
/// than computing the inverse in one-shot cases.
/**
* Solve A * x = b, where b is a column vector. This is more efficient
* than computing the inverse in one-shot cases.
*/
Solve(b_x, b_y, out) {

@@ -582,4 +684,6 @@ const a11 = this.ex.x;

}
/// Multiply a matrix times a vector. If a rotation matrix is provided,
/// then this transforms the vector from one frame to another.
/**
* Multiply a matrix times a vector. If a rotation matrix is provided,
* then this transforms the vector from one frame to another.
*/
static MultiplyVec2(M, v, out) {

@@ -592,4 +696,6 @@ const v_x = v.x;

}
/// Multiply a matrix transpose times a vector. If a rotation matrix is provided,
/// then this transforms the vector from one frame to another (inverse transform).
/**
* Multiply a matrix transpose times a vector. If a rotation matrix is provided,
* then this transforms the vector from one frame to another (inverse transform).
*/
static TransposeMultiplyVec2(M, v, out) {

@@ -644,3 +750,5 @@ const v_x = v.x;

b2Mat22.IDENTITY = new b2Mat22();
/// A 3-by-3 matrix. Stored in column-major order.
/**
* A 3-by-3 matrix. Stored in column-major order.
*/
class b2Mat33 {

@@ -655,3 +763,5 @@ constructor() {

}
/// Set this matrix using columns.
/**
* Set this matrix using columns.
*/
SetColumns(c1, c2, c3) {

@@ -675,3 +785,5 @@ this.ex.Copy(c1);

}
/// Set this matrix to all zeros.
/**
* Set this matrix to all zeros.
*/
SetZero() {

@@ -689,4 +801,6 @@ this.ex.SetZero();

}
/// Solve A * x = b, where b is a column vector. This is more efficient
/// than computing the inverse in one-shot cases.
/**
* Solve A * x = b, where b is a column vector. This is more efficient
* than computing the inverse in one-shot cases.
*/
Solve33(b_x, b_y, b_z, out) {

@@ -711,5 +825,7 @@ const a11 = this.ex.x;

}
/// Solve A * x = b, where b is a column vector. This is more efficient
/// than computing the inverse in one-shot cases. Solve only the upper
/// 2-by-2 matrix equation.
/**
* Solve A * x = b, where b is a column vector. This is more efficient
* than computing the inverse in one-shot cases. Solve only the upper
* 2-by-2 matrix equation.
*/
Solve22(b_x, b_y, out) {

@@ -728,4 +844,6 @@ const a11 = this.ex.x;

}
/// Get the inverse of this matrix as a 2-by-2.
/// Returns the zero matrix if singular.
/**
* Get the inverse of this matrix as a 2-by-2.
* Returns the zero matrix if singular.
*/
GetInverse22(M) {

@@ -750,4 +868,6 @@ const a = this.ex.x;

}
/// Get the symmetric inverse of this matrix as a 3-by-3.
/// Returns the zero matrix if singular.
/**
* Get the symmetric inverse of this matrix as a 3-by-3.
* Returns the zero matrix if singular.
*/
GetSymInverse33(M) {

@@ -774,3 +894,5 @@ let det = b2Vec3.Dot(this.ex, b2Vec3.Cross(this.ey, this.ez, b2Vec3.s_t0));

}
/// Multiply a matrix times a vector.
/**
* Multiply a matrix times a vector.
*/
static MultiplyVec3(A, v, out) {

@@ -783,3 +905,5 @@ const { x, y, z } = v;

}
/// Multiply a matrix times a vector.
/**
* Multiply a matrix times a vector.
*/
static MultiplyVec2(A, v, out) {

@@ -794,9 +918,13 @@ const { x, y } = v;

b2Mat33.IDENTITY = new b2Mat33();
/// Rotation
/**
* Rotation
*/
class b2Rot {
/// Initialize from an angle in radians
/**
* Initialize from an angle in radians
*/
constructor(angle = 0) {
/// Sine
/** Sine */
this.s = 0;
/// Cosine
/** Cosine */
this.c = 1;

@@ -816,3 +944,5 @@ if (angle) {

}
/// Set using an angle in radians.
/**
* Set using an angle in radians.
*/
Set(angle) {

@@ -823,3 +953,5 @@ this.s = Math.sin(angle);

}
/// Set to the identity rotation
/**
* Set to the identity rotation
*/
SetIdentity() {

@@ -830,7 +962,11 @@ this.s = 0;

}
/// Get the angle in radians
/**
* Get the angle in radians
*/
GetAngle() {
return Math.atan2(this.s, this.c);
}
/// Get the x-axis
/**
* Get the x-axis
*/
GetXAxis(out) {

@@ -841,3 +977,5 @@ out.x = this.c;

}
/// Get the u-axis
/**
* Get the u-axis
*/
GetYAxis(out) {

@@ -848,3 +986,5 @@ out.x = -this.s;

}
/// Multiply two rotations: q * r
/**
* Multiply two rotations: q * r
*/
static Multiply(q, r, out) {

@@ -861,3 +1001,5 @@ // [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]

}
/// Transpose multiply two rotations: qT * r
/**
* Transpose multiply two rotations: qT * r
*/
static TransposeMultiply(q, r, out) {

@@ -874,3 +1016,5 @@ // [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]

}
/// Rotate a vector
/**
* Rotate a vector
*/
static MultiplyVec2(q, v, out) {

@@ -883,3 +1027,5 @@ const v_x = v.x;

}
/// Inverse rotate a vector
/**
* Inverse rotate a vector
*/
static TransposeMultiplyVec2(q, v, out) {

@@ -895,4 +1041,6 @@ const v_x = v.x;

b2Rot.IDENTITY = new b2Rot();
/// A transform contains translation and rotation. It is used to represent
/// the position and orientation of rigid frames.
/**
* A transform contains translation and rotation. It is used to represent
* the position and orientation of rigid frames.
*/
class b2Transform {

@@ -911,3 +1059,5 @@ constructor() {

}
/// Set this to the identity transform.
/**
* Set this to the identity transform.
*/
SetIdentity() {

@@ -918,3 +1068,5 @@ this.p.SetZero();

}
/// Set this based on the position and rotation.
/**
* Set this based on the position and rotation.
*/
SetPositionRotation(position, q) {

@@ -925,3 +1077,5 @@ this.p.Copy(position);

}
/// Set this based on the position and angle.
/**
* Set this based on the position and angle.
*/
SetPositionAngle(pos, a) {

@@ -988,18 +1142,24 @@ this.p.Copy(pos);

b2Transform.IDENTITY = new b2Transform();
/// This describes the motion of a body/shape for TOI computation.
/// Shapes are defined with respect to the body origin, which may
/// no coincide with the center of mass. However, to support dynamics
/// we must interpolate the center of mass position.
/**
* This describes the motion of a body/shape for TOI computation.
* Shapes are defined with respect to the body origin, which may
* no coincide with the center of mass. However, to support dynamics
* we must interpolate the center of mass position.
*/
class b2Sweep {
constructor() {
/// < local center of mass position
/** Local center of mass position */
this.localCenter = new b2Vec2();
/// < center world positions
/** Center world position at time 0 */
this.c0 = new b2Vec2();
/** Center world position at time 1 */
this.c = new b2Vec2();
/// < world angles
/** World angle at time 0 */
this.a0 = 0;
/** World angle at time 1 */
this.a = 0;
/// Fraction of the current time step in the range [0,1]
/// c0 and a0 are the positions at alpha0.
/**
* Fraction of the current time step in the range [0,1]
* c0 and a0 are the positions at alpha0.
*/
this.alpha0 = 0;

@@ -1019,8 +1179,11 @@ }

}
/// Get the interpolated transform at a specific time.
/// @param transform the output transform
/// @param beta is a factor in [0,1], where 0 indicates alpha0.
// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
/**
* Get the interpolated transform at a specific time.
*
* @param transform The output transform
* @param beta Is a factor in [0,1], where 0 indicates alpha0.
* @see https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
*/
GetTransform(xf, beta) {
const oneMinusBeta = 1.0 - beta;
const oneMinusBeta = 1 - beta;
xf.p.x = oneMinusBeta * this.c0.x + beta * this.c.x;

@@ -1034,7 +1197,10 @@ xf.p.y = oneMinusBeta * this.c0.y + beta * this.c.y;

}
/// Advance the sweep forward, yielding a new initial state.
/// @param alpha the new initial time.
/**
* Advance the sweep forward, yielding a new initial state.
*
* @param alpha The new initial time.
*/
Advance(alpha) {
// DEBUG: b2Assert(this.alpha0 < 1);
const beta = (alpha - this.alpha0) / (1.0 - this.alpha0);
const beta = (alpha - this.alpha0) / (1 - this.alpha0);
this.c0.x += beta * (this.c.x - this.c0.x);

@@ -1045,3 +1211,5 @@ this.c0.y += beta * (this.c.y - this.c0.y);

}
/// Normalize an angle in radians to be between -pi and pi
/**
* Normalize an angle in radians to be between -pi and pi
*/
Normalize() {

@@ -1048,0 +1216,0 @@ const d = exports.b2_two_pi * Math.floor(this.a0 / exports.b2_two_pi);

@@ -0,3 +1,11 @@

/**
* You can use this to change the length scale used by your game.
* For example for inches you could use 39.4.
*/
export declare const b2_lengthUnitsPerMeter = 1;
/**
* The maximum number of vertices on a convex polygon. You cannot increase
* this too much because b2BlockAllocator has a maximum object size.
*/
export declare const b2_maxPolygonVertices = 8;
//# sourceMappingURL=b2_settings.d.ts.map

@@ -23,7 +23,11 @@ "use strict";

// TODO: Make this overridable by user as box2d allows it too.
/// You can use this to change the length scale used by your game.
/// For example for inches you could use 39.4.
/**
* You can use this to change the length scale used by your game.
* For example for inches you could use 39.4.
*/
exports.b2_lengthUnitsPerMeter = 1;
/// The maximum number of vertices on a convex polygon. You cannot increase
/// this too much because b2BlockAllocator has a maximum object size.
/**
* The maximum number of vertices on a convex polygon. You cannot increase
* this too much because b2BlockAllocator has a maximum object size.
*/
exports.b2_maxPolygonVertices = 8;

@@ -0,6 +1,16 @@

/**
* Timer for profiling. This has platform specific code and may
* not work on every platform.
*/
export declare class b2Timer {
m_start: number;
private m_start;
/**
* Reset the timer.
*/
Reset(): b2Timer;
/**
* Get the time since construction or the last reset.
*/
GetMilliseconds(): number;
}
//# sourceMappingURL=b2_timer.d.ts.map

@@ -21,4 +21,6 @@ "use strict";

exports.b2Timer = void 0;
/// Timer for profiling. This has platform specific code and may
/// not work on every platform.
/**
* Timer for profiling. This has platform specific code and may
* not work on every platform.
*/
class b2Timer {

@@ -28,3 +30,5 @@ constructor() {

}
/// Reset the timer.
/**
* Reset the timer.
*/
Reset() {

@@ -34,3 +38,5 @@ this.m_start = performance.now();

}
/// Get the time since construction or the last reset.
/**
* Get the time since construction or the last reset.
*/
GetMilliseconds() {

@@ -37,0 +43,0 @@ return performance.now() - this.m_start;

@@ -0,0 +0,0 @@ import { b2Vec2, XY } from "../common/b2_math";

@@ -43,4 +43,4 @@ "use strict";

this.m_targetLengths = b2_common_1.b2MakeNumberArray(def.bodies.length);
this.m_normals = b2_math_1.b2Vec2.MakeArray(def.bodies.length);
this.m_deltas = b2_math_1.b2Vec2.MakeArray(def.bodies.length);
this.m_normals = b2_common_1.b2MakeArray(def.bodies.length, b2_math_1.b2Vec2);
this.m_deltas = b2_common_1.b2MakeArray(def.bodies.length, b2_math_1.b2Vec2);
const djd = new b2_distance_joint_1.b2DistanceJointDef();

@@ -47,0 +47,0 @@ djd.stiffness = this.m_stiffness;

import { b2Vec2, b2Transform, b2Sweep, XY } from "../common/b2_math";
import { b2Shape, b2MassData } from "../collision/b2_shape";
import { b2MassData } from "../collision/b2_shape";
import type { b2ContactEdge } from "./b2_contact";

@@ -7,2 +7,8 @@ import { b2JointEdge } from "./b2_joint";

import type { b2World } from "./b2_world";
/**
* The body type.
* static: zero mass, zero velocity, may be manually moved
* kinematic: zero mass, non-zero velocity set by user, moved by solver
* dynamic: positive mass, non-zero velocity determined by forces, moved by solver
*/
export declare enum b2BodyType {

@@ -13,82 +19,257 @@ b2_staticBody = 0,

}
/**
* A body definition holds all the data needed to construct a rigid body.
* You can safely re-use body definitions. Shapes are added to a body after construction.
*/
export interface b2BodyDef {
/**
* The body type: static, kinematic, or dynamic.
* Note: if a dynamic body would have zero mass, the mass is set to one.
*/
type?: b2BodyType;
/**
* The world position of the body. Avoid creating bodies at the origin
* since this can lead to many overlapping shapes.
*/
position?: XY;
/** The world angle of the body in radians. */
angle?: number;
/** The linear velocity of the body's origin in world co-ordinates. */
linearVelocity?: XY;
/** The angular velocity of the body. */
angularVelocity?: number;
/**
* Linear damping is use to reduce the linear velocity. The damping parameter
* can be larger than 1 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 but the damping effect becomes sensitive to the
* time step when the damping parameter is large.
* Units are 1/time
*/
angularDamping?: 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;
/** 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;
/** Does this body start out enabled? */
enabled?: boolean;
/** Use this to store application specific body data. */
userData?: any;
/** Scale the gravity applied to this body. */
gravityScale?: number;
}
/**
* A rigid body. These are created via b2World::CreateBody.
*/
export declare class b2Body {
m_type: b2BodyType;
m_islandFlag: boolean;
m_awakeFlag: boolean;
m_autoSleepFlag: boolean;
m_bulletFlag: boolean;
m_fixedRotationFlag: boolean;
m_enabledFlag: boolean;
m_toiFlag: boolean;
m_islandIndex: number;
readonly m_xf: b2Transform;
readonly m_sweep: b2Sweep;
readonly m_linearVelocity: b2Vec2;
m_angularVelocity: number;
readonly m_force: b2Vec2;
m_torque: number;
m_world: b2World;
m_prev: b2Body | null;
m_next: b2Body | null;
m_fixtureList: b2Fixture | null;
m_fixtureCount: number;
m_jointList: b2JointEdge | null;
m_contactList: b2ContactEdge | null;
m_mass: number;
m_invMass: number;
m_I: number;
m_invI: number;
m_linearDamping: number;
m_angularDamping: number;
m_gravityScale: number;
m_sleepTime: number;
m_userData: any;
constructor(bd: b2BodyDef, world: b2World);
private m_type;
private m_islandFlag;
private m_awakeFlag;
private m_autoSleepFlag;
private m_bulletFlag;
private m_fixedRotationFlag;
private m_enabledFlag;
private m_toiFlag;
private m_islandIndex;
private readonly m_xf;
private readonly m_sweep;
private readonly m_linearVelocity;
private m_angularVelocity;
private readonly m_force;
private m_torque;
private readonly m_world;
private m_prev;
private m_next;
private m_fixtureList;
private m_fixtureCount;
private m_jointList;
private m_contactList;
private m_mass;
private m_invMass;
private m_I;
private m_invI;
private m_linearDamping;
private m_angularDamping;
private m_gravityScale;
private m_sleepTime;
private m_userData;
private constructor();
/**
* Creates a fixture and attach it to this body. Use this function if you need
* to set some fixture parameters, like friction. Otherwise you can create the
* fixture directly from a shape.
* If the density is non-zero, this function automatically updates the mass of the body.
* Contacts are not created until the next time step.
*
* @param def The fixture definition.
* @warning This function is locked during callbacks.
*/
CreateFixture(def: b2FixtureDef): b2Fixture;
CreateFixture(shape: b2Shape): b2Fixture;
CreateFixture(shape: b2Shape, density: number): b2Fixture;
CreateFixtureDef(def: b2FixtureDef): b2Fixture;
CreateShapeFixture(shape: b2Shape, density?: number): b2Fixture;
/**
* Destroy a fixture. This removes the fixture from the broad-phase and
* destroys all contacts associated with this fixture. This will
* automatically adjust the mass of the body if the body is dynamic and the
* fixture has positive density.
* All fixtures attached to a body are implicitly destroyed when the body is destroyed.
*
* @param fixture The fixture to be removed.
* @warning This function is locked during callbacks.
*/
DestroyFixture(fixture: b2Fixture): void;
/**
* Set the position of the body's origin and rotation.
* This breaks any contacts and wakes the other bodies.
* Manipulating a body's transform may cause non-physical behavior.
*
* @param position The world position of the body's local origin.
* @param angle The world rotation in radians.
*/
SetTransformVec(position: XY, angle: number): void;
SetTransformXY(x: number, y: number, angle: number): void;
SetTransform(xf: b2Transform): void;
/**
* Get the body transform for the body's origin.
*
* @returns The world transform of the body's origin.
*/
GetTransform(): Readonly<b2Transform>;
/**
* Get the world body origin position.
*
* @returns The world position of the body's origin.
*/
GetPosition(): Readonly<b2Vec2>;
SetPosition(position: XY): void;
SetPositionXY(x: number, y: number): void;
/**
* Get the angle in radians.
*
* @returns The current world rotation angle in radians.
*/
GetAngle(): number;
SetAngle(angle: number): void;
/**
* Get the world position of the center of mass.
*/
GetWorldCenter(): Readonly<b2Vec2>;
/**
* Get the local position of the center of mass.
*/
GetLocalCenter(): Readonly<b2Vec2>;
/**
* Set the linear velocity of the center of mass.
*
* @param v The new linear velocity of the center of mass.
*/
SetLinearVelocity(v: XY): void;
/**
* Get the linear velocity of the center of mass.
*
* @returns The linear velocity of the center of mass.
*/
GetLinearVelocity(): Readonly<b2Vec2>;
/**
* Set the angular velocity.
*
* @param omega The new angular velocity in radians/second.
*/
SetAngularVelocity(w: number): void;
/**
* Get the angular velocity.
*
* @returns The angular velocity in radians/second.
*/
GetAngularVelocity(): number;
/**
* Apply a force at a world point. If the force is not
* applied at the center of mass, it will generate a torque and
* affect the angular velocity. This wakes up the body.
*
* @param force The world force vector, usually in Newtons (N).
* @param point The world position of the point of application.
* @param wake Also wake up the body
*/
ApplyForce(force: XY, point: XY, wake?: boolean): void;
/**
* Apply a force to the center of mass. This wakes up the body.
*
* @param force The world force vector, usually in Newtons (N).
* @param wake Also wake up the body
*/
ApplyForceToCenter(force: XY, wake?: boolean): void;
/**
* Apply a torque. This affects the angular velocity
* without affecting the linear velocity of the center of mass.
*
* @param torque About the z-axis (out of the screen), usually in N-m.
* @param wake Also wake up the body
*/
ApplyTorque(torque: number, wake?: boolean): void;
/**
* Apply an impulse at a point. This immediately modifies the velocity.
* It also modifies the angular velocity if the point of application
* is not at the center of mass. This wakes up the body.
*
* @param impulse The world impulse vector, usually in N-seconds or kg-m/s.
* @param point The world position of the point of application.
* @param wake Also wake up the body
*/
ApplyLinearImpulse(impulse: XY, point: XY, wake?: boolean): void;
/**
* Apply an impulse at the center of gravity. This immediately modifies the velocity.
*
* @param impulse The world impulse vector, usually in N-seconds or kg-m/s.
* @param wake Also wake up the body
*/
ApplyLinearImpulseToCenter(impulse: XY, wake?: boolean): void;
/**
* Apply an angular impulse.
*
* @param impulse The angular impulse in units of kg*m*m/s
* @param wake Also wake up the body
*/
ApplyAngularImpulse(impulse: number, wake?: boolean): void;
/**
* Get the total mass of the body.
*
* @returns The mass, usually in kilograms (kg).
*/
GetMass(): number;
/**
* Get the rotational inertia of the body about the local origin.
*
* @returns The rotational inertia, usually in kg-m^2.
*/
GetInertia(): number;
/**
* Get the mass data of the body.
*
* @returns A struct containing the mass, inertia and center of the body.
*/
GetMassData(data: b2MassData): b2MassData;
private static SetMassData_s_oldCenter;
/**
* Set the mass properties to override the mass properties of the fixtures.
* Note that this changes the center of mass position.
* Note that creating or destroying fixtures can also alter the mass.
* This function has no effect if the body isn't dynamic.
*
* @param massData The mass properties.
*/
SetMassData(massData: b2MassData): void;

@@ -98,41 +279,178 @@ private static ResetMassData_s_localCenter;

private static ResetMassData_s_massData;
/**
* This resets the mass properties to the sum of the mass properties of the fixtures.
* This normally does not need to be called unless you called SetMassData to override
* the mass and you later want to reset the mass.
*/
ResetMassData(): void;
/**
* Get the world coordinates of a point given the local coordinates.
*
* @param localPoint A point on the body measured relative the the body's origin.
* @returns The same point expressed in world coordinates.
*/
GetWorldPoint<T extends XY>(localPoint: Readonly<XY>, out: T): T;
/**
* Get the world coordinates of a vector given the local coordinates.
*
* @param localVector A vector fixed in the body.
* @returns The same vector expressed in world coordinates.
*/
GetWorldVector<T extends XY>(localVector: Readonly<XY>, out: T): T;
/**
* Gets a local point relative to the body's origin given a world point.
*
* @param a Point in world coordinates.
* @returns The corresponding local point relative to the body's origin.
*/
GetLocalPoint<T extends XY>(worldPoint: Readonly<XY>, out: T): T;
/**
* Gets a local vector given a world vector.
*
* @param a Vector in world coordinates.
* @returns The corresponding local vector.
*/
GetLocalVector<T extends XY>(worldVector: Readonly<XY>, out: T): T;
/**
* Get the world linear velocity of a world point attached to this body.
*
* @param a Point in world coordinates.
* @returns The world velocity of a point.
*/
GetLinearVelocityFromWorldPoint<T extends XY>(worldPoint: Readonly<XY>, out: T): T;
/**
* Get the world velocity of a local point.
*
* @param a Point in local coordinates.
* @returns The world velocity of a point.
*/
GetLinearVelocityFromLocalPoint<T extends XY>(localPoint: Readonly<XY>, out: T): T;
/**
* Get the linear damping of the body.
*/
GetLinearDamping(): number;
/**
* Set the linear damping of the body.
*/
SetLinearDamping(linearDamping: number): void;
/**
* Get the angular damping of the body.
*/
GetAngularDamping(): number;
/**
* Set the angular damping of the body.
*/
SetAngularDamping(angularDamping: number): void;
/**
* Get the gravity scale of the body.
*/
GetGravityScale(): number;
/**
* Set the gravity scale of the body.
*/
SetGravityScale(scale: number): void;
/**
* Set the type of this body. This may alter the mass and velocity.
*/
SetType(type: b2BodyType): void;
/**
* Get the type of this body.
*/
GetType(): b2BodyType;
/**
* Should this body be treated like a bullet for continuous collision detection?
*/
SetBullet(flag: boolean): void;
/**
* Is this body treated like a bullet for continuous collision detection?
*/
IsBullet(): boolean;
/**
* You can disable sleeping on this body. If you disable sleeping, the
* body will be woken.
*/
SetSleepingAllowed(flag: boolean): void;
/**
* Is this body allowed to sleep
*/
IsSleepingAllowed(): boolean;
/**
* Set the sleep state of the body. A sleeping body has very
* low CPU cost.
*
* @param flag Set to true to wake the body, false to put it to sleep.
*/
SetAwake(flag: boolean): void;
/**
* Get the sleeping state of this body.
*
* @returns true if the body is sleeping.
*/
IsAwake(): boolean;
/**
* Allow a body to be disabled. A disabled body is not simulated and cannot
* be collided with or woken up.
* If you pass a flag of true, all fixtures will be added to the broad-phase.
* If you pass a flag of false, all fixtures will be removed from the
* broad-phase and all contacts will be destroyed.
* Fixtures and joints are otherwise unaffected. You may continue
* to create/destroy fixtures and joints on disabled bodies.
* Fixtures on a disabled body are implicitly disabled and will
* not participate in collisions, ray-casts, or queries.
* Joints connected to a disabled body are implicitly disabled.
* An disabled body is still owned by a b2World object and remains
* in the body list.
*/
SetEnabled(flag: boolean): void;
/**
* Get the active state of the body.
*/
IsEnabled(): boolean;
/**
* Set this body to have fixed rotation. This causes the mass
* to be reset.
*/
SetFixedRotation(flag: boolean): void;
/**
* Does this body have fixed rotation?
*/
IsFixedRotation(): boolean;
/**
* Get the list of all fixtures attached to this body.
*/
GetFixtureList(): b2Fixture | null;
/**
* Get the list of all joints attached to this body.
*/
GetJointList(): b2JointEdge | null;
/**
* Get the list of all contacts attached to this body.
*
* @warning this list changes during the time step and you may
* miss some collisions if you don't use b2ContactListener.
*/
GetContactList(): b2ContactEdge | null;
/**
* Get the next body in the world's body list.
*/
GetNext(): b2Body | null;
/**
* Get the user data pointer that was provided in the body definition.
*/
GetUserData(): any;
/**
* Set the user data. Use this to store your application specific data.
*/
SetUserData(data: any): void;
/**
* Get the parent world of this body.
*/
GetWorld(): b2World;
private static SynchronizeFixtures_s_xf1;
SynchronizeFixtures(): void;
SynchronizeTransform(): void;
ShouldCollide(other: b2Body): boolean;
ShouldCollideConnected(other: b2Body): boolean;
Advance(alpha: number): void;
private SynchronizeFixtures;
private SynchronizeTransform;
private ShouldCollide;
private ShouldCollideConnected;
private Advance;
}
//# sourceMappingURL=b2_body.d.ts.map

@@ -26,6 +26,8 @@ "use strict";

const b2_common_1 = require("../common/b2_common");
/// The body type.
/// static: zero mass, zero velocity, may be manually moved
/// kinematic: zero mass, non-zero velocity set by user, moved by solver
/// dynamic: positive mass, non-zero velocity determined by forces, moved by solver
/**
* The body type.
* static: zero mass, zero velocity, may be manually moved
* kinematic: zero mass, non-zero velocity set by user, moved by solver
* dynamic: positive mass, non-zero velocity determined by forces, moved by solver
*/
var b2BodyType;

@@ -37,36 +39,71 @@ (function (b2BodyType) {

})(b2BodyType = exports.b2BodyType || (exports.b2BodyType = {}));
/// A rigid body. These are created via b2World::CreateBody.
/**
* A rigid body. These are created via b2World::CreateBody.
*/
class b2Body {
/** @internal */
constructor(bd, world) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
/** @internal */
this.m_type = b2BodyType.b2_staticBody;
/** @internal */
this.m_islandFlag = false;
/** @internal */
this.m_awakeFlag = false;
/** @internal */
this.m_autoSleepFlag = false;
/** @internal */
this.m_bulletFlag = false;
/** @internal */
this.m_fixedRotationFlag = false;
/** @internal */
this.m_enabledFlag = false;
/** @internal */
this.m_toiFlag = false;
/** @internal */
this.m_islandIndex = 0;
/** @internal */
this.m_xf = new b2_math_1.b2Transform(); // the body origin transform
/** @internal */
this.m_sweep = new b2_math_1.b2Sweep(); // the swept motion for CCD
/** @internal */
this.m_linearVelocity = new b2_math_1.b2Vec2();
/** @internal */
this.m_angularVelocity = 0;
/** @internal */
this.m_force = new b2_math_1.b2Vec2();
/** @internal */
this.m_torque = 0;
/** @internal */
this.m_prev = null;
/** @internal */
this.m_next = null;
/** @internal */
this.m_fixtureList = null;
/** @internal */
this.m_fixtureCount = 0;
/** @internal */
this.m_jointList = null;
/** @internal */
this.m_contactList = null;
/** @internal */
this.m_mass = 1;
/** @internal */
this.m_invMass = 1;
// Rotational inertia about the center of mass.
/**
* Rotational inertia about the center of mass.
* @internal
*/
this.m_I = 0;
/** @internal */
this.m_invI = 0;
/** @internal */
this.m_linearDamping = 0;
/** @internal */
this.m_angularDamping = 0;
/** @internal */
this.m_gravityScale = 1;
/** @internal */
this.m_sleepTime = 0;
/** @internal */
this.m_userData = null;

@@ -105,17 +142,13 @@ this.m_bulletFlag = (_a = bd.bullet) !== null && _a !== void 0 ? _a : false;

}
CreateFixture(a, b = 0) {
if (a instanceof b2_shape_1.b2Shape) {
// fixme: call directly to avoid overload check
return this.CreateShapeFixture(a, b);
}
return this.CreateFixtureDef(a);
}
/// Creates a fixture and attach it to this body. Use this function if you need
/// to set some fixture parameters, like friction. Otherwise you can create the
/// fixture directly from a shape.
/// If the density is non-zero, this function automatically updates the mass of the body.
/// Contacts are not created until the next time step.
/// @param def the fixture definition.
/// @warning This function is locked during callbacks.
CreateFixtureDef(def) {
/**
* Creates a fixture and attach it to this body. Use this function if you need
* to set some fixture parameters, like friction. Otherwise you can create the
* fixture directly from a shape.
* If the density is non-zero, this function automatically updates the mass of the body.
* Contacts are not created until the next time step.
*
* @param def The fixture definition.
* @warning This function is locked during callbacks.
*/
CreateFixture(def) {
b2_common_1.b2Assert(!this.m_world.IsLocked());

@@ -139,19 +172,12 @@ const fixture = new b2_fixture_1.b2Fixture(this, def);

}
/// Creates a fixture from a shape and attach it to this body.
/// This is a convenience function. Use b2FixtureDef if you need to set parameters
/// like friction, restitution, user data, or filtering.
/// If the density is non-zero, this function automatically updates the mass of the body.
/// @param shape the shape to be cloned.
/// @param density the shape density (set to zero for static bodies).
/// @warning This function is locked during callbacks.
CreateShapeFixture(shape, density = 0) {
return this.CreateFixtureDef({ shape, density });
}
/// Destroy a fixture. This removes the fixture from the broad-phase and
/// destroys all contacts associated with this fixture. This will
/// automatically adjust the mass of the body if the body is dynamic and the
/// fixture has positive density.
/// All fixtures attached to a body are implicitly destroyed when the body is destroyed.
/// @param fixture the fixture to be removed.
/// @warning This function is locked during callbacks.
/**
* Destroy a fixture. This removes the fixture from the broad-phase and
* destroys all contacts associated with this fixture. This will
* automatically adjust the mass of the body if the body is dynamic and the
* fixture has positive density.
* All fixtures attached to a body are implicitly destroyed when the body is destroyed.
*
* @param fixture The fixture to be removed.
* @warning This function is locked during callbacks.
*/
DestroyFixture(fixture) {

@@ -204,7 +230,10 @@ b2_common_1.b2Assert(!this.m_world.IsLocked());

}
/// Set the position of the body's origin and rotation.
/// This breaks any contacts and wakes the other bodies.
/// Manipulating a body's transform may cause non-physical behavior.
/// @param position the world position of the body's local origin.
/// @param angle the world rotation in radians.
/**
* Set the position of the body's origin and rotation.
* This breaks any contacts and wakes the other bodies.
* Manipulating a body's transform may cause non-physical behavior.
*
* @param position The world position of the body's local origin.
* @param angle The world rotation in radians.
*/
SetTransformVec(position, angle) {

@@ -231,20 +260,23 @@ this.SetTransformXY(position.x, position.y, angle);

}
/// Get the body transform for the body's origin.
/// @return the world transform of the body's origin.
/**
* Get the body transform for the body's origin.
*
* @returns The world transform of the body's origin.
*/
GetTransform() {
return this.m_xf;
}
/// Get the world body origin position.
/// @return the world position of the body's origin.
/**
* Get the world body origin position.
*
* @returns The world position of the body's origin.
*/
GetPosition() {
return this.m_xf.p;
}
SetPosition(position) {
this.SetTransformVec(position, this.GetAngle());
}
SetPositionXY(x, y) {
this.SetTransformXY(x, y, this.GetAngle());
}
/// Get the angle in radians.
/// @return the current world rotation angle in radians.
/**
* Get the angle in radians.
*
* @returns The current world rotation angle in radians.
*/
GetAngle() {

@@ -256,12 +288,19 @@ return this.m_sweep.a;

}
/// Get the world position of the center of mass.
/**
* Get the world position of the center of mass.
*/
GetWorldCenter() {
return this.m_sweep.c;
}
/// Get the local position of the center of mass.
/**
* Get the local position of the center of mass.
*/
GetLocalCenter() {
return this.m_sweep.localCenter;
}
/// Set the linear velocity of the center of mass.
/// @param v the new linear velocity of the center of mass.
/**
* Set the linear velocity of the center of mass.
*
* @param v The new linear velocity of the center of mass.
*/
SetLinearVelocity(v) {

@@ -276,9 +315,15 @@ if (this.m_type === b2BodyType.b2_staticBody) {

}
/// Get the linear velocity of the center of mass.
/// @return the linear velocity of the center of mass.
/**
* Get the linear velocity of the center of mass.
*
* @returns The linear velocity of the center of mass.
*/
GetLinearVelocity() {
return this.m_linearVelocity;
}
/// Set the angular velocity.
/// @param omega the new angular velocity in radians/second.
/**
* Set the angular velocity.
*
* @param omega The new angular velocity in radians/second.
*/
SetAngularVelocity(w) {

@@ -293,13 +338,19 @@ if (this.m_type === b2BodyType.b2_staticBody) {

}
/// Get the angular velocity.
/// @return the angular velocity in radians/second.
/**
* Get the angular velocity.
*
* @returns The angular velocity in radians/second.
*/
GetAngularVelocity() {
return this.m_angularVelocity;
}
/// Apply a force at a world point. If the force is not
/// applied at the center of mass, it will generate a torque and
/// affect the angular velocity. This wakes up the body.
/// @param force the world force vector, usually in Newtons (N).
/// @param point the world position of the point of application.
/// @param wake also wake up the body
/**
* Apply a force at a world point. If the force is not
* applied at the center of mass, it will generate a torque and
* affect the angular velocity. This wakes up the body.
*
* @param force The world force vector, usually in Newtons (N).
* @param point The world position of the point of application.
* @param wake Also wake up the body
*/
ApplyForce(force, point, wake = true) {

@@ -319,5 +370,8 @@ if (this.m_type !== b2BodyType.b2_dynamicBody) {

}
/// Apply a force to the center of mass. This wakes up the body.
/// @param force the world force vector, usually in Newtons (N).
/// @param wake also wake up the body
/**
* Apply a force to the center of mass. This wakes up the body.
*
* @param force The world force vector, usually in Newtons (N).
* @param wake Also wake up the body
*/
ApplyForceToCenter(force, wake = true) {

@@ -336,6 +390,9 @@ if (this.m_type !== b2BodyType.b2_dynamicBody) {

}
/// Apply a torque. This affects the angular velocity
/// without affecting the linear velocity of the center of mass.
/// @param torque about the z-axis (out of the screen), usually in N-m.
/// @param wake also wake up the body
/**
* Apply a torque. This affects the angular velocity
* without affecting the linear velocity of the center of mass.
*
* @param torque About the z-axis (out of the screen), usually in N-m.
* @param wake Also wake up the body
*/
ApplyTorque(torque, wake = true) {

@@ -353,8 +410,11 @@ if (this.m_type !== b2BodyType.b2_dynamicBody) {

}
/// Apply an impulse at a point. This immediately modifies the velocity.
/// It also modifies the angular velocity if the point of application
/// is not at the center of mass. This wakes up the body.
/// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
/// @param point the world position of the point of application.
/// @param wake also wake up the body
/**
* Apply an impulse at a point. This immediately modifies the velocity.
* It also modifies the angular velocity if the point of application
* is not at the center of mass. This wakes up the body.
*
* @param impulse The world impulse vector, usually in N-seconds or kg-m/s.
* @param point The world position of the point of application.
* @param wake Also wake up the body
*/
ApplyLinearImpulse(impulse, point, wake = true) {

@@ -375,5 +435,8 @@ if (this.m_type !== b2BodyType.b2_dynamicBody) {

}
/// Apply an impulse at the center of gravity. This immediately modifies the velocity.
/// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
/// @param wake also wake up the body
/**
* Apply an impulse at the center of gravity. This immediately modifies the velocity.
*
* @param impulse The world impulse vector, usually in N-seconds or kg-m/s.
* @param wake Also wake up the body
*/
ApplyLinearImpulseToCenter(impulse, wake = true) {

@@ -392,5 +455,8 @@ if (this.m_type !== b2BodyType.b2_dynamicBody) {

}
/// Apply an angular impulse.
/// @param impulse the angular impulse in units of kg*m*m/s
/// @param wake also wake up the body
/**
* Apply an angular impulse.
*
* @param impulse The angular impulse in units of kg*m*m/s
* @param wake Also wake up the body
*/
ApplyAngularImpulse(impulse, wake = true) {

@@ -408,14 +474,23 @@ if (this.m_type !== b2BodyType.b2_dynamicBody) {

}
/// Get the total mass of the body.
/// @return the mass, usually in kilograms (kg).
/**
* Get the total mass of the body.
*
* @returns The mass, usually in kilograms (kg).
*/
GetMass() {
return this.m_mass;
}
/// Get the rotational inertia of the body about the local origin.
/// @return the rotational inertia, usually in kg-m^2.
/**
* Get the rotational inertia of the body about the local origin.
*
* @returns The rotational inertia, usually in kg-m^2.
*/
GetInertia() {
return this.m_I + this.m_mass * b2_math_1.b2Vec2.Dot(this.m_sweep.localCenter, this.m_sweep.localCenter);
}
/// Get the mass data of the body.
/// @return a struct containing the mass, inertia and center of the body.
/**
* Get the mass data of the body.
*
* @returns A struct containing the mass, inertia and center of the body.
*/
GetMassData(data) {

@@ -427,2 +502,10 @@ data.mass = this.m_mass;

}
/**
* Set the mass properties to override the mass properties of the fixtures.
* Note that this changes the center of mass position.
* Note that creating or destroying fixtures can also alter the mass.
* This function has no effect if the body isn't dynamic.
*
* @param massData The mass properties.
*/
SetMassData(massData) {

@@ -454,2 +537,7 @@ b2_common_1.b2Assert(!this.m_world.IsLocked());

}
/**
* This resets the mass properties to the sum of the mass properties of the fixtures.
* This normally does not need to be called unless you called SetMassData to override
* the mass and you later want to reset the mass.
*/
ResetMassData() {

@@ -478,4 +566,3 @@ // Compute mass data from shapes. Each shape has its own density.

this.m_mass += massData.mass;
localCenter.x += massData.center.x * massData.mass;
localCenter.y += massData.center.y * massData.mass;
localCenter.AddScaled(massData.mass, massData.center);
this.m_I += massData.I;

@@ -486,4 +573,3 @@ }

this.m_invMass = 1 / this.m_mass;
localCenter.x *= this.m_invMass;
localCenter.y *= this.m_invMass;
localCenter.Scale(this.m_invMass);
}

@@ -508,63 +594,95 @@ if (this.m_I > 0 && !this.m_fixedRotationFlag) {

}
/// Get the world coordinates of a point given the local coordinates.
/// @param localPoint a point on the body measured relative the the body's origin.
/// @return the same point expressed in world coordinates.
/**
* Get the world coordinates of a point given the local coordinates.
*
* @param localPoint A point on the body measured relative the the body's origin.
* @returns The same point expressed in world coordinates.
*/
GetWorldPoint(localPoint, out) {
return b2_math_1.b2Transform.MultiplyVec2(this.m_xf, localPoint, out);
}
/// Get the world coordinates of a vector given the local coordinates.
/// @param localVector a vector fixed in the body.
/// @return the same vector expressed in world coordinates.
/**
* Get the world coordinates of a vector given the local coordinates.
*
* @param localVector A vector fixed in the body.
* @returns The same vector expressed in world coordinates.
*/
GetWorldVector(localVector, out) {
return b2_math_1.b2Rot.MultiplyVec2(this.m_xf.q, localVector, out);
}
/// Gets a local point relative to the body's origin given a world point.
/// @param a point in world coordinates.
/// @return the corresponding local point relative to the body's origin.
/**
* Gets a local point relative to the body's origin given a world point.
*
* @param a Point in world coordinates.
* @returns The corresponding local point relative to the body's origin.
*/
GetLocalPoint(worldPoint, out) {
return b2_math_1.b2Transform.TransposeMultiplyVec2(this.m_xf, worldPoint, out);
}
/// Gets a local vector given a world vector.
/// @param a vector in world coordinates.
/// @return the corresponding local vector.
/**
* Gets a local vector given a world vector.
*
* @param a Vector in world coordinates.
* @returns The corresponding local vector.
*/
GetLocalVector(worldVector, out) {
return b2_math_1.b2Rot.TransposeMultiplyVec2(this.m_xf.q, worldVector, out);
}
/// Get the world linear velocity of a world point attached to this body.
/// @param a point in world coordinates.
/// @return the world velocity of a point.
/**
* Get the world linear velocity of a world point attached to this body.
*
* @param a Point in world coordinates.
* @returns The world velocity of a point.
*/
GetLinearVelocityFromWorldPoint(worldPoint, out) {
return b2_math_1.b2Vec2.AddCrossScalarVec2(this.m_linearVelocity, this.m_angularVelocity, b2_math_1.b2Vec2.Subtract(worldPoint, this.m_sweep.c, b2_math_1.b2Vec2.s_t0), out);
}
/// Get the world velocity of a local point.
/// @param a point in local coordinates.
/// @return the world velocity of a point.
/**
* Get the world velocity of a local point.
*
* @param a Point in local coordinates.
* @returns The world velocity of a point.
*/
GetLinearVelocityFromLocalPoint(localPoint, out) {
return this.GetLinearVelocityFromWorldPoint(this.GetWorldPoint(localPoint, out), out);
}
/// Get the linear damping of the body.
/**
* Get the linear damping of the body.
*/
GetLinearDamping() {
return this.m_linearDamping;
}
/// Set the linear damping of the body.
/**
* Set the linear damping of the body.
*/
SetLinearDamping(linearDamping) {
this.m_linearDamping = linearDamping;
}
/// Get the angular damping of the body.
/**
* Get the angular damping of the body.
*/
GetAngularDamping() {
return this.m_angularDamping;
}
/// Set the angular damping of the body.
/**
* Set the angular damping of the body.
*/
SetAngularDamping(angularDamping) {
this.m_angularDamping = angularDamping;
}
/// Get the gravity scale of the body.
/**
* Get the gravity scale of the body.
*/
GetGravityScale() {
return this.m_gravityScale;
}
/// Set the gravity scale of the body.
/**
* Set the gravity scale of the body.
*/
SetGravityScale(scale) {
this.m_gravityScale = scale;
}
/// Set the type of this body. This may alter the mass and velocity.
/**
* Set the type of this body. This may alter the mass and velocity.
*/
SetType(type) {

@@ -599,19 +717,29 @@ b2_common_1.b2Assert(!this.m_world.IsLocked());

for (let f = this.m_fixtureList; f; f = f.m_next) {
f.TouchProxies(broadPhase);
for (const proxy of f.m_proxies) {
broadPhase.TouchProxy(proxy.treeNode);
}
}
}
/// Get the type of this body.
/**
* Get the type of this body.
*/
GetType() {
return this.m_type;
}
/// Should this body be treated like a bullet for continuous collision detection?
/**
* Should this body be treated like a bullet for continuous collision detection?
*/
SetBullet(flag) {
this.m_bulletFlag = flag;
}
/// Is this body treated like a bullet for continuous collision detection?
/**
* Is this body treated like a bullet for continuous collision detection?
*/
IsBullet() {
return this.m_bulletFlag;
}
/// You can disable sleeping on this body. If you disable sleeping, the
/// body will be woken.
/**
* You can disable sleeping on this body. If you disable sleeping, the
* body will be woken.
*/
SetSleepingAllowed(flag) {

@@ -623,9 +751,14 @@ this.m_autoSleepFlag = flag;

}
/// Is this body allowed to sleep
/**
* Is this body allowed to sleep
*/
IsSleepingAllowed() {
return this.m_autoSleepFlag;
}
/// Set the sleep state of the body. A sleeping body has very
/// low CPU cost.
/// @param flag set to true to wake the body, false to put it to sleep.
/**
* Set the sleep state of the body. A sleeping body has very
* low CPU cost.
*
* @param flag Set to true to wake the body, false to put it to sleep.
*/
SetAwake(flag) {

@@ -648,19 +781,24 @@ if (this.m_type === b2BodyType.b2_staticBody) {

}
/// Get the sleeping state of this body.
/// @return true if the body is sleeping.
/**
* Get the sleeping state of this body.
*
* @returns true if the body is sleeping.
*/
IsAwake() {
return this.m_awakeFlag;
}
/// Allow a body to be disabled. A disabled body is not simulated and cannot
/// be collided with or woken up.
/// If you pass a flag of true, all fixtures will be added to the broad-phase.
/// If you pass a flag of false, all fixtures will be removed from the
/// broad-phase and all contacts will be destroyed.
/// Fixtures and joints are otherwise unaffected. You may continue
/// to create/destroy fixtures and joints on disabled bodies.
/// Fixtures on a disabled body are implicitly disabled and will
/// not participate in collisions, ray-casts, or queries.
/// Joints connected to a disabled body are implicitly disabled.
/// An diabled body is still owned by a b2World object and remains
/// in the body list.
/**
* Allow a body to be disabled. A disabled body is not simulated and cannot
* be collided with or woken up.
* If you pass a flag of true, all fixtures will be added to the broad-phase.
* If you pass a flag of false, all fixtures will be removed from the
* broad-phase and all contacts will be destroyed.
* Fixtures and joints are otherwise unaffected. You may continue
* to create/destroy fixtures and joints on disabled bodies.
* Fixtures on a disabled body are implicitly disabled and will
* not participate in collisions, ray-casts, or queries.
* Joints connected to a disabled body are implicitly disabled.
* An disabled body is still owned by a b2World object and remains
* in the body list.
*/
SetEnabled(flag) {

@@ -696,8 +834,12 @@ b2_common_1.b2Assert(!this.m_world.IsLocked());

}
/// Get the active state of the body.
/**
* Get the active state of the body.
*/
IsEnabled() {
return this.m_enabledFlag;
}
/// Set this body to have fixed rotation. This causes the mass
/// to be reset.
/**
* Set this body to have fixed rotation. This causes the mass
* to be reset.
*/
SetFixedRotation(flag) {

@@ -711,36 +853,54 @@ if (this.m_fixedRotationFlag === flag) {

}
/// Does this body have fixed rotation?
/**
* Does this body have fixed rotation?
*/
IsFixedRotation() {
return this.m_fixedRotationFlag;
}
/// Get the list of all fixtures attached to this body.
/**
* Get the list of all fixtures attached to this body.
*/
GetFixtureList() {
return this.m_fixtureList;
}
/// Get the list of all joints attached to this body.
/**
* Get the list of all joints attached to this body.
*/
GetJointList() {
return this.m_jointList;
}
/// Get the list of all contacts attached to this body.
/// @warning this list changes during the time step and you may
/// miss some collisions if you don't use b2ContactListener.
/**
* Get the list of all contacts attached to this body.
*
* @warning this list changes during the time step and you may
* miss some collisions if you don't use b2ContactListener.
*/
GetContactList() {
return this.m_contactList;
}
/// Get the next body in the world's body list.
/**
* Get the next body in the world's body list.
*/
GetNext() {
return this.m_next;
}
/// Get the user data pointer that was provided in the body definition.
/**
* Get the user data pointer that was provided in the body definition.
*/
GetUserData() {
return this.m_userData;
}
/// Set the user data. Use this to store your application specific data.
/**
* Set the user data. Use this to store your application specific data.
*/
SetUserData(data) {
this.m_userData = data;
}
/// Get the parent world of this body.
/**
* Get the parent world of this body.
*/
GetWorld() {
return this.m_world;
}
/** @internal */
SynchronizeFixtures() {

@@ -763,2 +923,3 @@ const broadPhase = this.m_world.m_contactManager.m_broadPhase;

}
/** @internal */
SynchronizeTransform() {

@@ -769,7 +930,11 @@ this.m_xf.q.Set(this.m_sweep.a);

}
// This is used to prevent connected bodies from colliding.
// It may lie, depending on the collideConnected flag.
/**
* This is used to prevent connected bodies from colliding.
* It may lie, depending on the collideConnected flag.
*
* @internal
*/
ShouldCollide(other) {
// At least one body should be dynamic or kinematic.
if (this.m_type === b2BodyType.b2_staticBody && other.m_type === b2BodyType.b2_staticBody) {
// At least one body should be dynamic.
if (this.m_type !== b2BodyType.b2_dynamicBody && other.m_type !== b2BodyType.b2_dynamicBody) {
return false;

@@ -790,2 +955,3 @@ }

}
/** @internal */
Advance(alpha) {

@@ -802,11 +968,3 @@ // Advance to the new safe time. This doesn't sync the broad-phase.

exports.b2Body = b2Body;
/// Set the mass properties to override the mass properties of the fixtures.
/// Note that this changes the center of mass position.
/// Note that creating or destroying fixtures can also alter the mass.
/// This function has no effect if the body isn't dynamic.
/// @param massData the mass properties.
b2Body.SetMassData_s_oldCenter = new b2_math_1.b2Vec2();
/// This resets the mass properties to the sum of the mass properties of the fixtures.
/// This normally does not need to be called unless you called SetMassData to override
/// the mass and you later want to reset the mass.
b2Body.ResetMassData_s_localCenter = new b2_math_1.b2Vec2();

@@ -813,0 +971,0 @@ b2Body.ResetMassData_s_oldCenter = new b2_math_1.b2Vec2();

@@ -5,7 +5,2 @@ import { b2Transform } from "../common/b2_math";

import { b2CircleShape } from "../collision/b2_circle_shape";
import { b2Contact } from "./b2_contact";
export declare class b2ChainAndCircleContact extends b2Contact<b2ChainShape, b2CircleShape> {
private static Evaluate_s_edge;
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_chain_circle_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -24,2 +24,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2ChainAndCircleContact extends b2_contact_1.b2Contact {

@@ -26,0 +27,0 @@ Evaluate(manifold, xfA, xfB) {

@@ -5,7 +5,2 @@ import { b2Transform } from "../common/b2_math";

import { b2PolygonShape } from "../collision/b2_polygon_shape";
import { b2Contact } from "./b2_contact";
export declare class b2ChainAndPolygonContact extends b2Contact<b2ChainShape, b2PolygonShape> {
private static Evaluate_s_edge;
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_chain_polygon_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -24,2 +24,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2ChainAndPolygonContact extends b2_contact_1.b2Contact {

@@ -26,0 +27,0 @@ Evaluate(manifold, xfA, xfB) {

import { b2Transform } from "../common/b2_math";
import { b2Manifold } from "../collision/b2_collision";
import { b2CircleShape } from "../collision/b2_circle_shape";
import { b2Contact } from "./b2_contact";
export declare class b2CircleContact extends b2Contact<b2CircleShape, b2CircleShape> {
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_circle_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -23,2 +23,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2CircleContact extends b2_contact_1.b2Contact {

@@ -25,0 +26,0 @@ Evaluate(manifold, xfA, xfB) {

@@ -0,0 +0,0 @@ import { b2Contact } from "./b2_contact";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { b2BroadPhase } from "../collision/b2_broad_phase";

@@ -182,4 +182,6 @@ "use strict";

if (c.m_filterFlag) {
if (
// Should these bodies collide?
if (!bodyB.ShouldCollide(bodyA) ||
!bodyB.ShouldCollide(bodyA) ||
// Check user filtering.
(this.m_contactFilter && !this.m_contactFilter.ShouldCollide(fixtureA, fixtureB))) {

@@ -186,0 +188,0 @@ const cNuke = c;

@@ -1,7 +0,8 @@

import { b2Vec2, b2Mat22, b2Transform } from "../common/b2_math";
import { b2Vec2, b2Mat22 } from "../common/b2_math";
import { b2ManifoldType } from "../collision/b2_collision";
import { b2Contact } from "./b2_contact";
import { b2TimeStep, b2Position, b2Velocity } from "./b2_time_step";
export declare const b2SetBlockSolve: (value: boolean) => void;
export declare class b2VelocityConstraintPoint {
export declare function b2SetBlockSolve(value: boolean): void;
export declare function b2GetBlockSolve(): boolean;
declare class b2VelocityConstraintPoint {
readonly rA: b2Vec2;

@@ -14,25 +15,4 @@ readonly rB: b2Vec2;

velocityBias: number;
static MakeArray(length: number): b2VelocityConstraintPoint[];
}
export declare class b2ContactVelocityConstraint {
readonly points: b2VelocityConstraintPoint[];
readonly normal: b2Vec2;
readonly tangent: b2Vec2;
readonly normalMass: b2Mat22;
readonly K: b2Mat22;
indexA: number;
indexB: number;
invMassA: number;
invMassB: number;
invIA: number;
invIB: number;
friction: number;
restitution: number;
threshold: number;
tangentSpeed: number;
pointCount: number;
contactIndex: number;
static MakeArray(length: number): b2ContactVelocityConstraint[];
}
export declare class b2ContactPositionConstraint {
declare class b2ContactPositionConstraint {
readonly localPoints: b2Vec2[];

@@ -53,64 +33,4 @@ readonly localNormal: b2Vec2;

pointCount: number;
static MakeArray(length: number): b2ContactPositionConstraint[];
}
export declare class b2ContactSolverDef {
readonly step: b2TimeStep;
contacts: b2Contact[];
count: number;
positions: b2Position[];
velocities: b2Velocity[];
}
export declare class b2PositionSolverManifold {
readonly normal: b2Vec2;
readonly point: b2Vec2;
separation: number;
private static Initialize_s_pointA;
private static Initialize_s_pointB;
private static Initialize_s_planePoint;
private static Initialize_s_clipPoint;
Initialize(pc: b2ContactPositionConstraint, xfA: b2Transform, xfB: b2Transform, index: number): void;
}
export declare class b2ContactSolver {
readonly m_step: b2TimeStep;
m_positions: b2Position[];
m_velocities: b2Velocity[];
readonly m_positionConstraints: b2ContactPositionConstraint[];
readonly m_velocityConstraints: b2ContactVelocityConstraint[];
m_contacts: b2Contact[];
m_count: number;
Initialize(def: b2ContactSolverDef): b2ContactSolver;
private static InitializeVelocityConstraints_s_xfA;
private static InitializeVelocityConstraints_s_xfB;
private static InitializeVelocityConstraints_s_worldManifold;
InitializeVelocityConstraints(): void;
private static WarmStart_s_P;
WarmStart(): void;
private static SolveVelocityConstraints_s_dv;
private static SolveVelocityConstraints_s_dv1;
private static SolveVelocityConstraints_s_dv2;
private static SolveVelocityConstraints_s_P;
private static SolveVelocityConstraints_s_a;
private static SolveVelocityConstraints_s_b;
private static SolveVelocityConstraints_s_x;
private static SolveVelocityConstraints_s_d;
private static SolveVelocityConstraints_s_P1;
private static SolveVelocityConstraints_s_P2;
private static SolveVelocityConstraints_s_P1P2;
SolveVelocityConstraints(): void;
StoreImpulses(): void;
private static SolvePositionConstraints_s_xfA;
private static SolvePositionConstraints_s_xfB;
private static SolvePositionConstraints_s_psm;
private static SolvePositionConstraints_s_rA;
private static SolvePositionConstraints_s_rB;
private static SolvePositionConstraints_s_P;
SolvePositionConstraints(): boolean;
private static SolveTOIPositionConstraints_s_xfA;
private static SolveTOIPositionConstraints_s_xfB;
private static SolveTOIPositionConstraints_s_psm;
private static SolveTOIPositionConstraints_s_rA;
private static SolveTOIPositionConstraints_s_rB;
private static SolveTOIPositionConstraints_s_P;
SolveTOIPositionConstraints(toiIndexA: number, toiIndexB: number): boolean;
}
export {};
//# sourceMappingURL=b2_contact_solver.d.ts.map

@@ -20,3 +20,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2ContactSolver = exports.b2PositionSolverManifold = exports.b2ContactSolverDef = exports.b2ContactPositionConstraint = exports.b2ContactVelocityConstraint = exports.b2VelocityConstraintPoint = exports.b2SetBlockSolve = void 0;
exports.b2ContactSolver = exports.b2ContactSolverDef = exports.b2ContactVelocityConstraint = exports.b2GetBlockSolve = exports.b2SetBlockSolve = void 0;
// DEBUG: import { b2Assert } from "../common/b2_common";

@@ -30,5 +30,10 @@ const b2_common_1 = require("../common/b2_common");

let g_blockSolve = true;
exports.b2SetBlockSolve = (value) => {
function b2SetBlockSolve(value) {
g_blockSolve = value;
};
}
exports.b2SetBlockSolve = b2SetBlockSolve;
function b2GetBlockSolve() {
return g_blockSolve;
}
exports.b2GetBlockSolve = b2GetBlockSolve;
class b2VelocityConstraintPoint {

@@ -44,13 +49,7 @@ constructor() {

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2VelocityConstraintPoint();
return result;
}
}
exports.b2VelocityConstraintPoint = b2VelocityConstraintPoint;
/** @internal */
class b2ContactVelocityConstraint {
constructor() {
this.points = b2VelocityConstraintPoint.MakeArray(b2_common_1.b2_maxManifoldPoints);
this.points = b2_common_1.b2MakeArray(b2_common_1.b2_maxManifoldPoints, b2VelocityConstraintPoint);
this.normal = new b2_math_1.b2Vec2();

@@ -73,8 +72,2 @@ this.tangent = new b2_math_1.b2Vec2();

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2ContactVelocityConstraint();
return result;
}
}

@@ -84,3 +77,3 @@ exports.b2ContactVelocityConstraint = b2ContactVelocityConstraint;

constructor() {
this.localPoints = b2_math_1.b2Vec2.MakeArray(b2_common_1.b2_maxManifoldPoints);
this.localPoints = b2_common_1.b2MakeArray(b2_common_1.b2_maxManifoldPoints, b2_math_1.b2Vec2);
this.localNormal = new b2_math_1.b2Vec2();

@@ -101,10 +94,4 @@ this.localPoint = new b2_math_1.b2Vec2();

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2ContactPositionConstraint();
return result;
}
}
exports.b2ContactPositionConstraint = b2ContactPositionConstraint;
/** @internal */
class b2ContactSolverDef {

@@ -130,3 +117,3 @@ constructor() {

switch (pc.type) {
case b2_collision_1.b2ManifoldType.e_circles: {
case b2_collision_1.b2ManifoldType.e_circles:
b2_math_1.b2Transform.MultiplyVec2(xfA, pc.localPoint, pointA);

@@ -139,4 +126,3 @@ b2_math_1.b2Transform.MultiplyVec2(xfB, pc.localPoints[0], pointB);

break;
}
case b2_collision_1.b2ManifoldType.e_faceA: {
case b2_collision_1.b2ManifoldType.e_faceA:
b2_math_1.b2Rot.MultiplyVec2(xfA.q, pc.localNormal, this.normal);

@@ -151,4 +137,3 @@ b2_math_1.b2Transform.MultiplyVec2(xfA, pc.localPoint, planePoint);

break;
}
case b2_collision_1.b2ManifoldType.e_faceB: {
case b2_collision_1.b2ManifoldType.e_faceB:
b2_math_1.b2Rot.MultiplyVec2(xfB.q, pc.localNormal, this.normal);

@@ -165,7 +150,5 @@ b2_math_1.b2Transform.MultiplyVec2(xfB, pc.localPoint, planePoint);

break;
}
}
}
}
exports.b2PositionSolverManifold = b2PositionSolverManifold;
b2PositionSolverManifold.Initialize_s_pointA = new b2_math_1.b2Vec2();

@@ -175,7 +158,8 @@ b2PositionSolverManifold.Initialize_s_pointB = new b2_math_1.b2Vec2();

b2PositionSolverManifold.Initialize_s_clipPoint = new b2_math_1.b2Vec2();
/** @internal */
class b2ContactSolver {
constructor() {
this.m_step = b2_time_step_1.b2TimeStep.Create();
this.m_positionConstraints = b2ContactPositionConstraint.MakeArray(1024); // TODO: b2Settings
this.m_velocityConstraints = b2ContactVelocityConstraint.MakeArray(1024); // TODO: b2Settings
this.m_positionConstraints = b2_common_1.b2MakeArray(1024, b2ContactPositionConstraint); // TODO: b2Settings
this.m_velocityConstraints = b2_common_1.b2MakeArray(1024, b2ContactVelocityConstraint); // TODO: b2Settings
this.m_count = 0;

@@ -399,3 +383,2 @@ }

// Relative velocity at contact
// b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
b2_math_1.b2Vec2.Subtract(b2_math_1.b2Vec2.AddCrossScalarVec2(vB, wB, vcp.rB, b2_math_1.b2Vec2.s_t0), b2_math_1.b2Vec2.AddCrossScalarVec2(vA, wA, vcp.rA, b2_math_1.b2Vec2.s_t1), dv);

@@ -422,3 +405,2 @@ // Compute tangent force

// Relative velocity at contact
// b2Vec2 dv = vB + b2Cross(wB, vcp->rB) - vA - b2Cross(wA, vcp->rA);
b2_math_1.b2Vec2.Subtract(b2_math_1.b2Vec2.AddCrossScalarVec2(vB, wB, vcp.rB, b2_math_1.b2Vec2.s_t0), b2_math_1.b2Vec2.AddCrossScalarVec2(vA, wA, vcp.rA, b2_math_1.b2Vec2.s_t1), dv);

@@ -429,3 +411,2 @@ // Compute normal impulse

// b2Clamp the accumulated impulse
// float32 newImpulse = Math.max(vcp->normalImpulse + lambda, 0.0f);
const newImpulse = Math.max(vcp.normalImpulse + lambda, 0);

@@ -489,7 +470,5 @@ lambda = newImpulse - vcp.normalImpulse;

b.Subtract(b2_math_1.b2Mat22.MultiplyVec2(vc.K, a, b2_math_1.b2Vec2.s_t0));
/*
#if B2_DEBUG_SOLVER === 1
const k_errorTol = 1e-3f;
#endif
*/
// #if B2_DEBUG_SOLVER === 1
// const k_errorTol = 1e-3f;
// #endif
for (;;) {

@@ -522,16 +501,12 @@ //

cp2.normalImpulse = x.y;
/*
#if B2_DEBUG_SOLVER === 1
// Postconditions
dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
// Compute normal velocity
vn1 = b2Dot(dv1, normal);
vn2 = b2Dot(dv2, normal);
b2Assert(Math.abs(vn1 - cp1->velocityBias) < k_errorTol);
b2Assert(Math.abs(vn2 - cp2->velocityBias) < k_errorTol);
#endif
*/
// #if B2_DEBUG_SOLVER === 1
// // Postconditions
// dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
// dv2 = vB + b2Cross(wB, cp2->rB) - vA - b2Cross(wA, cp2->rA);
// // Compute normal velocity
// vn1 = b2Dot(dv1, normal);
// vn2 = b2Dot(dv2, normal);
// b2Assert(Math.abs(vn1 - cp1->velocityBias) < k_errorTol);
// b2Assert(Math.abs(vn2 - cp2->velocityBias) < k_errorTol);
// #endif
break;

@@ -564,13 +539,9 @@ }

cp2.normalImpulse = x.y;
/*
#if B2_DEBUG_SOLVER === 1
// Postconditions
dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
// Compute normal velocity
vn1 = b2Dot(dv1, normal);
b2Assert(Math.abs(vn1 - cp1->velocityBias) < k_errorTol);
#endif
*/
// #if B2_DEBUG_SOLVER === 1
// // Postconditions
// dv1 = vB + b2Cross(wB, cp1->rB) - vA - b2Cross(wA, cp1->rA);
// // Compute normal velocity
// vn1 = b2Dot(dv1, normal);
// b2Assert(Math.abs(vn1 - cp1->velocityBias) < k_errorTol);
// #endif
break;

@@ -577,0 +548,0 @@ }

@@ -1,2 +0,2 @@

import { b2Transform, b2Sweep } from "../common/b2_math";
import { b2Transform } from "../common/b2_math";
import { b2Manifold, b2WorldManifold } from "../collision/b2_collision";

@@ -7,11 +7,33 @@ import { b2Body } from "./b2_body";

import type { b2ContactListener } from "./b2_world_callbacks";
/**
* 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 b2MixFriction(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 b2MixRestitution(restitution1: number, restitution2: number): number;
/**
* Restitution mixing law. This picks the lowest value.
*/
export declare function b2MixRestitutionThreshold(threshold1: number, threshold2: 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 b2ContactEdge {
/** Provides quick access to the other body attached. */
private m_other;
get other(): b2Body;
set other(value: b2Body);
/** The contact */
readonly contact: b2Contact;
/** The previous contact edge in the body's contact list */
prev: b2ContactEdge | null;
/** The next contact edge in the body's contact list */
next: b2ContactEdge | null;

@@ -21,25 +43,54 @@ constructor(contact: b2Contact);

}
/**
* 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 abstract class b2Contact<A extends b2Shape = b2Shape, B extends b2Shape = b2Shape> {
m_islandFlag: boolean;
m_touchingFlag: boolean;
m_enabledFlag: boolean;
m_filterFlag: boolean;
m_bulletHitFlag: boolean;
m_toiFlag: boolean;
m_prev: b2Contact | null;
m_next: b2Contact | null;
readonly m_nodeA: b2ContactEdge;
readonly m_nodeB: b2ContactEdge;
m_fixtureA: b2Fixture;
m_fixtureB: b2Fixture;
m_indexA: number;
m_indexB: number;
m_manifold: b2Manifold;
m_toiCount: number;
m_toi: number;
m_friction: number;
m_restitution: number;
m_restitutionThreshold: number;
m_tangentSpeed: number;
m_oldManifold: b2Manifold;
/**
* Used when crawling contact graph when forming islands.
*/
protected m_islandFlag: boolean;
/**
* Set when the shapes are touching.
*/
protected m_touchingFlag: boolean;
/**
* This contact can be disabled (by user)
*/
protected m_enabledFlag: boolean;
/**
* This contact needs filtering because a fixture filter was changed.
*/
protected m_filterFlag: boolean;
/**
* This bullet contact had a TOI event
*/
protected m_bulletHitFlag: boolean;
/**
* This contact has a valid TOI in m_toi
*/
protected m_toiFlag: boolean;
/**
* World pool and list pointers.
*/
protected m_prev: b2Contact | null;
protected m_next: b2Contact | null;
/**
* Nodes for connecting bodies.
*/
protected readonly m_nodeA: b2ContactEdge;
protected readonly m_nodeB: b2ContactEdge;
protected m_fixtureA: b2Fixture;
protected m_fixtureB: b2Fixture;
protected m_indexA: number;
protected m_indexB: number;
protected m_manifold: b2Manifold;
protected m_toiCount: number;
protected m_toi: number;
protected m_friction: number;
protected m_restitution: number;
protected m_restitutionThreshold: number;
protected m_tangentSpeed: number;
protected m_oldManifold: b2Manifold;
GetManifold(): b2Manifold;

@@ -58,3 +109,3 @@ GetWorldManifold(worldManifold: b2WorldManifold): void;

abstract Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
FlagForFiltering(): void;
protected FlagForFiltering(): void;
SetFriction(friction: number): void;

@@ -66,4 +117,14 @@ GetFriction(): number;

ResetRestitution(): void;
/**
* Override the default restitution velocity threshold mixture. You can call this in b2ContactListener::PreSolve.
* The value persists until you set or reset.
*/
SetRestitutionThreshold(threshold: number): void;
/**
* Get the restitution threshold.
*/
GetRestitutionThreshold(): number;
/**
* Reset the restitution threshold to the default value.
*/
ResetRestitutionThreshold(): void;

@@ -73,7 +134,4 @@ SetTangentSpeed(speed: number): void;

Reset(fixtureA: b2Fixture, indexA: number, fixtureB: b2Fixture, indexB: number): void;
Update(listener: b2ContactListener): void;
private static ComputeTOI_s_input;
private static ComputeTOI_s_output;
ComputeTOI(sweepA: b2Sweep, sweepB: b2Sweep): number;
protected Update(listener: b2ContactListener): void;
}
//# sourceMappingURL=b2_contact.d.ts.map

@@ -23,5 +23,6 @@ "use strict";

const b2_collision_1 = require("../collision/b2_collision");
const b2_time_of_impact_1 = require("../collision/b2_time_of_impact");
/// Friction mixing law. The idea is to allow either fixture to drive the friction to zero.
/// For example, anything slides on ice.
/**
* Friction mixing law. The idea is to allow either fixture to drive the friction to zero.
* For example, anything slides on ice.
*/
function b2MixFriction(friction1, friction2) {

@@ -31,4 +32,6 @@ return Math.sqrt(friction1 * friction2);

exports.b2MixFriction = b2MixFriction;
/// Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.
/// For example, a superball bounces on anything.
/**
* Restitution mixing law. The idea is allow for anything to bounce off an inelastic surface.
* For example, a superball bounces on anything.
*/
function b2MixRestitution(restitution1, restitution2) {

@@ -38,3 +41,5 @@ return restitution1 > restitution2 ? restitution1 : restitution2;

exports.b2MixRestitution = b2MixRestitution;
/// Restitution mixing law. This picks the lowest value.
/**
* Restitution mixing law. This picks the lowest value.
*/
function b2MixRestitutionThreshold(threshold1, threshold2) {

@@ -44,12 +49,17 @@ return threshold1 < threshold2 ? threshold1 : threshold2;

exports.b2MixRestitutionThreshold = b2MixRestitutionThreshold;
/// 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.
/**
* 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.
*/
class b2ContactEdge {
constructor(contact) {
this.m_other = null; /// < provides quick access to the other body attached.
this.prev = null; /// < the previous contact edge in the body's contact list
this.next = null; /// < the next contact edge in the body's contact list
/** Provides quick access to the other body attached. */
this.m_other = null;
/** The previous contact edge in the body's contact list */
this.prev = null;
/** The next contact edge in the body's contact list */
this.next = null;
this.contact = contact;

@@ -72,22 +82,78 @@ }

exports.b2ContactEdge = b2ContactEdge;
/**
* 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.
*/
class b2Contact {
constructor() {
this.m_islandFlag = false; /// Used when crawling contact graph when forming islands.
this.m_touchingFlag = false; /// Set when the shapes are touching.
this.m_enabledFlag = false; /// This contact can be disabled (by user)
this.m_filterFlag = false; /// This contact needs filtering because a fixture filter was changed.
this.m_bulletHitFlag = false; /// This bullet contact had a TOI event
this.m_toiFlag = false; /// This contact has a valid TOI in m_toi
/**
* Used when crawling contact graph when forming islands.
*
* @internal protected
*/
this.m_islandFlag = false;
/**
* Set when the shapes are touching.
*
* @internal protected
*/
this.m_touchingFlag = false;
/**
* This contact can be disabled (by user)
*
* @internal protected
*/
this.m_enabledFlag = false;
/**
* This contact needs filtering because a fixture filter was changed.
*
* @internal protected
*/
this.m_filterFlag = false;
/**
* This bullet contact had a TOI event
*
* @internal protected
*/
this.m_bulletHitFlag = false;
/**
* This contact has a valid TOI in m_toi
*
* @internal protected
*/
this.m_toiFlag = false;
/**
* World pool and list pointers.
*
* @internal protected
*/
this.m_prev = null;
/** @internal protected */
this.m_next = null;
/**
* Nodes for connecting bodies.
*
* @internal protected
*/
this.m_nodeA = new b2ContactEdge(this);
/** @internal protected */
this.m_nodeB = new b2ContactEdge(this);
/** @internal protected */
this.m_indexA = 0;
/** @internal protected */
this.m_indexB = 0;
/** @internal protected */
this.m_manifold = new b2_collision_1.b2Manifold(); // TODO: readonly
/** @internal protected */
this.m_toiCount = 0;
/** @internal protected */
this.m_toi = 0;
/** @internal protected */
this.m_friction = 0;
/** @internal protected */
this.m_restitution = 0;
/** @internal protected */
this.m_restitutionThreshold = 0;
/** @internal protected */
this.m_tangentSpeed = 0;

@@ -136,2 +202,3 @@ this.m_oldManifold = new b2_collision_1.b2Manifold(); // TODO: readonly

}
/** @internal protected */
FlagForFiltering() {

@@ -158,12 +225,18 @@ this.m_filterFlag = true;

}
/// Override the default restitution velocity threshold mixture. You can call this in b2ContactListener::PreSolve.
/// The value persists until you set or reset.
/**
* Override the default restitution velocity threshold mixture. You can call this in b2ContactListener::PreSolve.
* The value persists until you set or reset.
*/
SetRestitutionThreshold(threshold) {
this.m_restitutionThreshold = threshold;
}
/// Get the restitution threshold.
/**
* Get the restitution threshold.
*/
GetRestitutionThreshold() {
return this.m_restitutionThreshold;
}
/// Reset the restitution threshold to the default value.
/**
* Reset the restitution threshold to the default value.
*/
ResetRestitutionThreshold() {

@@ -199,2 +272,3 @@ this.m_restitutionThreshold = b2MixRestitutionThreshold(this.m_fixtureA.m_restitutionThreshold, this.m_fixtureB.m_restitutionThreshold);

}
/** @internal protected */
Update(listener) {

@@ -219,3 +293,3 @@ const tManifold = this.m_oldManifold;

const shapeB = this.GetShapeB();
touching = b2_collision_1.b2TestOverlapShape(shapeA, this.m_indexA, shapeB, this.m_indexB, xfA, xfB);
touching = b2_collision_1.b2TestOverlap(shapeA, this.m_indexA, shapeB, this.m_indexB, xfA, xfB);
// Sensors don't generate manifolds.

@@ -259,16 +333,3 @@ this.m_manifold.pointCount = 0;

}
ComputeTOI(sweepA, sweepB) {
const input = b2Contact.ComputeTOI_s_input;
input.proxyA.SetShape(this.GetShapeA(), this.m_indexA);
input.proxyB.SetShape(this.GetShapeB(), this.m_indexB);
input.sweepA.Copy(sweepA);
input.sweepB.Copy(sweepB);
input.tMax = b2_common_1.b2_linearSlop;
const output = b2Contact.ComputeTOI_s_output;
b2_time_of_impact_1.b2TimeOfImpact(output, input);
return output.t;
}
}
exports.b2Contact = b2Contact;
b2Contact.ComputeTOI_s_input = new b2_time_of_impact_1.b2TOIInput();
b2Contact.ComputeTOI_s_output = new b2_time_of_impact_1.b2TOIOutput();

@@ -5,2 +5,3 @@ import { b2Vec2, XY } from "../common/b2_math";

import type { b2Body } from "./b2_body";
import { b2Draw } from "../common/b2_draw";
export interface b2IDistanceJointDef extends b2IJointDef {

@@ -15,9 +16,22 @@ localAnchorA: XY;

}
/**
* Distance joint definition. This requires defining an anchor point on both
* bodies and the non-zero distance of the distance joint. The definition uses
* local anchor points so that the initial configuration can violate the
* constraint slightly. This helps when saving and loading a game.
*/
export declare class b2DistanceJointDef extends b2JointDef implements b2IDistanceJointDef {
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The rest length of this joint. Clamped to a stable minimum value. */
length: number;
/** Minimum length. Clamped to a stable minimum value. */
minLength: number;
/** Maximum length. Must be greater than or equal to the minimum length. */
maxLength: number;
/** The linear stiffness in N/m. */
stiffness: number;
/** The linear damping in N*s/m. */
damping: number;

@@ -27,30 +41,34 @@ constructor();

}
/**
* A distance joint constrains two points on two bodies to remain at a fixed
* distance from each other. You can view this as a massless, rigid rod.
*/
export declare class b2DistanceJoint extends b2Joint {
m_stiffness: number;
m_damping: number;
m_bias: number;
m_length: number;
m_minLength: number;
m_maxLength: number;
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
m_gamma: number;
m_impulse: number;
m_lowerImpulse: number;
m_upperImpulse: number;
m_indexA: number;
m_indexB: number;
readonly m_u: b2Vec2;
readonly m_rA: b2Vec2;
readonly m_rB: b2Vec2;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_currentLength: number;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
m_softMass: number;
m_mass: number;
constructor(def: b2IDistanceJointDef);
protected m_stiffness: number;
protected m_damping: number;
protected m_bias: number;
protected m_length: number;
protected m_minLength: number;
protected m_maxLength: number;
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected m_gamma: number;
protected m_impulse: number;
protected m_lowerImpulse: number;
protected m_upperImpulse: number;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_u: b2Vec2;
protected readonly m_rA: b2Vec2;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_currentLength: number;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected m_softMass: number;
protected m_mass: number;
protected constructor(def: b2IDistanceJointDef);
GetAnchorA<T extends XY>(out: T): T;

@@ -62,7 +80,7 @@ GetAnchorB<T extends XY>(out: T): T;

GetLocalAnchorB(): Readonly<b2Vec2>;
SetLength(length: number): void;
SetLength(length: number): number;
GetLength(): number;
SetMinLength(minLength: number): void;
SetMinLength(minLength: number): number;
GetMinLength(): number;
SetMaxLength(maxLength: number): void;
SetMaxLength(maxLength: number): number;
GetMaxLength(): number;

@@ -74,6 +92,7 @@ GetCurrentLength(): number;

GetDamping(): number;
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(data: b2SolverData): boolean;
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(data: b2SolverData): boolean;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_distance_joint.d.ts.map

@@ -24,2 +24,3 @@ "use strict";

const b2_joint_1 = require("./b2_joint");
const b2_draw_1 = require("../common/b2_draw");
const temp = {

@@ -36,23 +37,33 @@ worldPointA: new b2_math_1.b2Vec2(),

lalcB: new b2_math_1.b2Vec2(),
Draw: {
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
axis: new b2_math_1.b2Vec2(),
pRest: new b2_math_1.b2Vec2(),
p1: new b2_math_1.b2Vec2(),
p2: new b2_math_1.b2Vec2(),
},
};
/// Distance joint definition. This requires defining an anchor point on both
/// bodies and the non-zero distance of the distance joint. The definition uses
/// local anchor points so that the initial configuration can violate the
/// constraint slightly. This helps when saving and loading a game.
/**
* Distance joint definition. This requires defining an anchor point on both
* bodies and the non-zero distance of the distance joint. The definition uses
* local anchor points so that the initial configuration can violate the
* constraint slightly. This helps when saving and loading a game.
*/
class b2DistanceJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_distanceJoint);
/// The local anchor point relative to bodyA's origin.
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2();
/// The local anchor point relative to bodyB's origin.
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2();
/// The rest length of this joint. Clamped to a stable minimum value.
/** The rest length of this joint. Clamped to a stable minimum value. */
this.length = 1;
/// Minimum length. Clamped to a stable minimum value.
/** Minimum length. Clamped to a stable minimum value. */
this.minLength = 0;
/// Maximum length. Must be greater than or equal to the minimum length.
/** Maximum length. Must be greater than or equal to the minimum length. */
this.maxLength = b2_common_1.b2_maxFloat;
/// The linear stiffness in N/m.
/** The linear stiffness in N/m. */
this.stiffness = 0;
/// The linear damping in N*s/m.
/** The linear damping in N*s/m. */
this.damping = 0;

@@ -71,5 +82,8 @@ }

exports.b2DistanceJointDef = b2DistanceJointDef;
/// A distance joint constrains two points on two bodies to remain at a fixed
/// distance from each other. You can view this as a massless, rigid rod.
/**
* A distance joint constrains two points on two bodies to remain at a fixed
* distance from each other. You can view this as a massless, rigid rod.
*/
class b2DistanceJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -133,2 +147,3 @@ var _a, _b;

this.m_length = Math.max(b2_common_1.b2_linearSlop, length);
return this.m_length;
}

@@ -141,2 +156,3 @@ GetLength() {

this.m_minLength = b2_math_1.b2Clamp(minLength, b2_common_1.b2_linearSlop, this.m_maxLength);
return this.m_minLength;
}

@@ -149,2 +165,3 @@ GetMinLength() {

this.m_maxLength = Math.max(maxLength, this.m_minLength);
return this.m_maxLength;
}

@@ -171,2 +188,3 @@ GetMaxLength() {

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -251,2 +269,3 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -323,2 +342,3 @@ const vA = data.velocities[this.m_indexA].v;

}
/** @internal protected */
SolvePositionConstraints(data) {

@@ -360,3 +380,25 @@ const cA = data.positions[this.m_indexA].c;

}
Draw(draw) {
const { pA, pB, axis, pRest } = temp.Draw;
const xfA = this.m_bodyA.GetTransform();
const xfB = this.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, this.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, this.m_localAnchorB, pB);
b2_math_1.b2Vec2.Subtract(pB, pA, axis);
axis.Normalize();
draw.DrawSegment(pA, pB, b2_draw_1.debugColors.joint5);
b2_math_1.b2Vec2.AddScaled(pA, this.m_length, axis, pRest);
draw.DrawPoint(pRest, 8, b2_draw_1.debugColors.joint1);
if (this.m_minLength !== this.m_maxLength) {
if (this.m_minLength > b2_common_1.b2_linearSlop) {
const pMin = b2_math_1.b2Vec2.AddScaled(pA, this.m_minLength, axis, temp.Draw.p1);
draw.DrawPoint(pMin, 4, b2_draw_1.debugColors.joint2);
}
if (this.m_maxLength < b2_common_1.b2_maxFloat) {
const pMax = b2_math_1.b2Vec2.AddScaled(pA, this.m_maxLength, axis, temp.Draw.p1);
draw.DrawPoint(pMax, 4, b2_draw_1.debugColors.joint3);
}
}
}
}
exports.b2DistanceJoint = b2DistanceJoint;

@@ -5,6 +5,2 @@ import { b2Transform } from "../common/b2_math";

import { b2EdgeShape } from "../collision/b2_edge_shape";
import { b2Contact } from "./b2_contact";
export declare class b2EdgeAndCircleContact extends b2Contact<b2EdgeShape, b2CircleShape> {
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_edge_circle_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -23,2 +23,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2EdgeAndCircleContact extends b2_contact_1.b2Contact {

@@ -25,0 +26,0 @@ Evaluate(manifold, xfA, xfB) {

@@ -5,6 +5,2 @@ import { b2Transform } from "../common/b2_math";

import { b2PolygonShape } from "../collision/b2_polygon_shape";
import { b2Contact } from "./b2_contact";
export declare class b2EdgeAndPolygonContact extends b2Contact<b2EdgeShape, b2PolygonShape> {
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_edge_polygon_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -23,2 +23,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2EdgeAndPolygonContact extends b2_contact_1.b2Contact {

@@ -25,0 +26,0 @@ Evaluate(manifold, xfA, xfB) {

@@ -7,18 +7,55 @@ import { b2Transform, XY } from "../common/b2_math";

import { b2BroadPhase } from "../collision/b2_broad_phase";
/**
* This holds contact filtering data.
*/
export interface b2Filter {
/** The collision category bits. Normally you would just set one bit. */
categoryBits: number;
/**
* The collision mask bits. This states the categories that this
* shape would accept for collision.
*/
maskBits: number;
/**
* Collision groups allow a certain group of objects to never collide (negative)
* or always collide (positive). Zero means no collision group. Non-zero group
* filtering always wins against the mask bits.
*/
groupIndex: number;
}
export declare const b2DefaultFilter: Readonly<b2Filter>;
/**
* A fixture definition is used to create a fixture. This class defines an
* abstract fixture definition. You can reuse fixture definitions safely.
*/
export interface b2FixtureDef {
/**
* The shape, this must be set. The shape will be cloned, so you
* can create the shape on the stack.
*/
shape: b2Shape;
/** Use this to store application specific fixture data. */
userData?: any;
/** The friction coefficient, usually in the range [0,1]. */
friction?: number;
/** The restitution (elasticity) usually in the range [0,1]. */
restitution?: number;
/**
* Restitution velocity threshold, usually in m/s. Collisions above this
* speed have restitution applied (will bounce).
*/
restitutionThreshold?: number;
/** The density, usually in kg/m^2. */
density?: number;
/**
* A sensor shape collects contact information but never generates a collision
* response.
*/
isSensor?: boolean;
/** Contact filtering data. */
filter?: Partial<b2Filter>;
}
/**
* This proxy is used internally to connect fixtures to the broad-phase.
*/
export declare class b2FixtureProxy {

@@ -31,42 +68,145 @@ readonly aabb: b2AABB;

}
/**
* 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.
* Fixtures are created via b2Body::CreateFixture.
*
* @warning you cannot reuse fixtures.
*/
export declare class b2Fixture {
m_density: number;
m_next: b2Fixture | null;
readonly m_body: b2Body;
readonly m_shape: b2Shape;
m_friction: number;
m_restitution: number;
m_restitutionThreshold: number;
readonly m_proxies: b2FixtureProxy[];
get m_proxyCount(): number;
readonly m_filter: b2Filter;
m_isSensor: boolean;
m_userData: any;
constructor(body: b2Body, def: b2FixtureDef);
protected m_density: number;
protected m_next: b2Fixture | null;
protected readonly m_body: b2Body;
protected readonly m_shape: b2Shape;
protected m_friction: number;
protected m_restitution: number;
protected m_restitutionThreshold: number;
protected readonly m_proxies: b2FixtureProxy[];
protected get m_proxyCount(): number;
protected readonly m_filter: b2Filter;
protected m_isSensor: boolean;
protected m_userData: any;
protected constructor(body: b2Body, def: b2FixtureDef);
/**
* Get the type of the child shape. You can use this to down cast to the concrete shape.
*
* @returns The shape type.
*/
GetType(): b2ShapeType;
/**
* 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(): b2Shape;
/**
* Set if this fixture is a sensor.
*/
SetSensor(sensor: boolean): void;
/**
* Is this fixture a sensor (non-solid)?
*
* @returns The true if the shape is a sensor.
*/
IsSensor(): boolean;
/**
* 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: Readonly<Partial<b2Filter>>): void;
/**
* Get the contact filtering data.
*/
GetFilterData(): Readonly<b2Filter>;
/**
* Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
*/
Refilter(): void;
/**
* Get the parent body of this fixture. This is NULL if the fixture is not attached.
*
* @returns The parent body.
*/
GetBody(): b2Body;
/**
* Get the next fixture in the parent body's fixture list.
*
* @returns The next shape.
*/
GetNext(): b2Fixture | null;
/**
* Get the user data that was assigned in the fixture definition. Use this to
* store your application specific data.
*/
GetUserData(): any;
/**
* Set the user data. Use this to store your application specific data.
*/
SetUserData(data: any): void;
/**
* Test a point for containment in this fixture.
*
* @param p A point in world coordinates.
*/
TestPoint(p: XY): boolean;
/**
* Cast a ray against this shape.
*
* @param output The ray-cast results.
* @param input The ray-cast input parameters.
*/
RayCast(output: b2RayCastOutput, input: b2RayCastInput, 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?: b2MassData): b2MassData;
/**
* Set the density of this fixture. This will _not_ automatically adjust the mass
* of the body. You must call b2Body::ResetMassData to update the body's mass.
*/
SetDensity(density: number): void;
/**
* Get the density of this fixture.
*/
GetDensity(): number;
/**
* Get the coefficient of friction.
*/
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;
SetRestitutionThreshold(threshold: number): 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): Readonly<b2AABB>;
CreateProxies(broadPhase: b2BroadPhase<b2FixtureProxy>, xf: b2Transform): void;
DestroyProxies(broadPhase: b2BroadPhase<b2FixtureProxy>): void;
TouchProxies(broadPhase: b2BroadPhase<b2FixtureProxy>): void;
Synchronize(broadPhase: b2BroadPhase<b2FixtureProxy>, transform1: b2Transform, transform2: b2Transform): void;
/**
* These support body activation/deactivation.
*/
protected CreateProxies(broadPhase: b2BroadPhase<b2FixtureProxy>, xf: b2Transform): void;
protected DestroyProxies(broadPhase: b2BroadPhase<b2FixtureProxy>): void;
protected Synchronize(
broadPhase: b2BroadPhase<b2FixtureProxy>,
transform1: b2Transform,
transform2: b2Transform
): void;
}
//# sourceMappingURL=b2_fixture.d.ts.map

@@ -36,3 +36,5 @@ "use strict";

};
/// This proxy is used internally to connect fixtures to the broad-phase.
/**
* This proxy is used internally to connect fixtures to the broad-phase.
*/
class b2FixtureProxy {

@@ -51,16 +53,27 @@ constructor(fixture, broadPhase, xf, childIndex) {

const Synchronize_s_displacement = new b2_math_1.b2Vec2();
/// 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.
/// Fixtures are created via b2Body::CreateFixture.
/// @warning you cannot reuse fixtures.
/**
* 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.
* Fixtures are created via b2Body::CreateFixture.
*
* @warning you cannot reuse fixtures.
*/
class b2Fixture {
/** @internal protected */
constructor(body, def) {
var _a, _b, _c, _d, _e;
/** @internal protected */
this.m_density = 0;
/** @internal protected */
this.m_next = null;
/** @internal protected */
this.m_friction = 0;
/** @internal protected */
this.m_restitution = 0;
/** @internal protected */
this.m_restitutionThreshold = 0;
/** @internal protected */
this.m_proxies = [];
/** @internal protected */
this.m_isSensor = false;

@@ -81,17 +94,25 @@ this.m_userData = null;

}
/** @internal protected */
get m_proxyCount() {
return this.m_proxies.length;
}
/// Get the type of the child shape. You can use this to down cast to the concrete shape.
/// @return the shape type.
/**
* Get the type of the child shape. You can use this to down cast to the concrete shape.
*
* @returns The shape type.
*/
GetType() {
return this.m_shape.GetType();
}
/// 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.
/**
* 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() {
return this.m_shape;
}
/// Set if this fixture is a sensor.
/**
* Set if this fixture is a sensor.
*/
SetSensor(sensor) {

@@ -103,10 +124,15 @@ if (sensor !== this.m_isSensor) {

}
/// Is this fixture a sensor (non-solid)?
/// @return the true if the shape is a sensor.
/**
* Is this fixture a sensor (non-solid)?
*
* @returns The true if the shape is a sensor.
*/
IsSensor() {
return this.m_isSensor;
}
/// 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.
/**
* 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) {

@@ -119,7 +145,11 @@ var _a, _b, _c;

}
/// Get the contact filtering data.
/**
* Get the contact filtering data.
*/
GetFilterData() {
return this.m_filter;
}
/// Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
/**
* Call this if you want to establish collision that was previously disabled by b2ContactFilter::ShouldCollide.
*/
Refilter() {

@@ -138,40 +168,59 @@ // Flag associated contacts for filtering.

const world = this.m_body.GetWorld();
if (world) {
// Touch each proxy so that new pairs may be created
this.TouchProxies(world.m_contactManager.m_broadPhase);
// Touch each proxy so that new pairs may be created
const broadPhase = world.m_contactManager.m_broadPhase;
for (const proxy of this.m_proxies) {
broadPhase.TouchProxy(proxy.treeNode);
}
}
/// Get the parent body of this fixture. This is NULL if the fixture is not attached.
/// @return the parent body.
/**
* Get the parent body of this fixture. This is NULL if the fixture is not attached.
*
* @returns The parent body.
*/
GetBody() {
return this.m_body;
}
/// Get the next fixture in the parent body's fixture list.
/// @return the next shape.
/**
* Get the next fixture in the parent body's fixture list.
*
* @returns The next shape.
*/
GetNext() {
return this.m_next;
}
/// Get the user data that was assigned in the fixture definition. Use this to
/// store your application specific data.
/**
* Get the user data that was assigned in the fixture definition. Use this to
* store your application specific data.
*/
GetUserData() {
return this.m_userData;
}
/// Set the user data. Use this to store your application specific data.
/**
* Set the user data. Use this to store your application specific data.
*/
SetUserData(data) {
this.m_userData = data;
}
/// Test a point for containment in this fixture.
/// @param p a point in world coordinates.
/**
* Test a point for containment in this fixture.
*
* @param p A point in world coordinates.
*/
TestPoint(p) {
return this.m_shape.TestPoint(this.m_body.GetTransform(), p);
}
/// Cast a ray against this shape.
/// @param output the ray-cast results.
/// @param input the ray-cast input parameters.
/**
* Cast a ray against this shape.
*
* @param output The ray-cast results.
* @param input The ray-cast input parameters.
*/
RayCast(output, input, childIndex) {
return this.m_shape.RayCast(output, input, this.m_body.GetTransform(), childIndex);
}
/// 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.
/**
* 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 = new b2_shape_1.b2MassData()) {

@@ -181,4 +230,6 @@ this.m_shape.ComputeMass(massData, this.m_density);

}
/// Set the density of this fixture. This will _not_ automatically adjust the mass
/// of the body. You must call b2Body::ResetMassData to update the body's mass.
/**
* Set the density of this fixture. This will _not_ automatically adjust the mass
* of the body. You must call b2Body::ResetMassData to update the body's mass.
*/
SetDensity(density) {

@@ -188,27 +239,42 @@ // DEBUG: b2Assert(Number.isFinite(density) && density >= 0);

}
/// Get the density of this fixture.
/**
* Get the density of this fixture.
*/
GetDensity() {
return this.m_density;
}
/// Get the coefficient of friction.
/**
* Get the coefficient of friction.
*/
GetFriction() {
return this.m_friction;
}
/// Set the coefficient of friction. This will _not_ change the friction of
/// existing contacts.
/**
* Set the coefficient of friction. This will _not_ change the friction of
* existing contacts.
*/
SetFriction(friction) {
this.m_friction = friction;
}
/// Get the coefficient of restitution.
/**
* Get the coefficient of restitution.
*/
GetRestitution() {
return this.m_restitution;
}
/// Set the coefficient of restitution. This will _not_ change the restitution of
/// existing contacts.
/**
* Set the coefficient of restitution. This will _not_ change the restitution of
* existing contacts.
*/
SetRestitution(restitution) {
this.m_restitution = restitution;
}
/// 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.
SetRestitutionThreshold(threshold) {
this.m_restitutionThreshold = threshold;
}
/**
* 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) {

@@ -218,3 +284,7 @@ // DEBUG: b2Assert(0 <= childIndex && childIndex < this.m_proxyCount);

}
// These support body activation/deactivation.
/**
* These support body activation/deactivation.
*
* @internal protected
*/
CreateProxies(broadPhase, xf) {

@@ -228,2 +298,3 @@ b2_common_1.b2Assert(this.m_proxies.length === 0);

}
/** @internal protected */
DestroyProxies(broadPhase) {

@@ -236,9 +307,6 @@ // Destroy proxies in the broad-phase.

}
TouchProxies(broadPhase) {
for (const proxy of this.m_proxies) {
broadPhase.TouchProxy(proxy.treeNode);
}
}
/** @internal protected */
Synchronize(broadPhase, transform1, transform2) {
const { c1, c2 } = temp;
const displacement = Synchronize_s_displacement;
for (const proxy of this.m_proxies) {

@@ -251,3 +319,2 @@ // Compute an AABB that covers the swept shape (may miss some rotation effect).

proxy.aabb.Combine2(aabb1, aabb2);
const displacement = Synchronize_s_displacement;
b2_math_1.b2Vec2.Subtract(aabb2.GetCenter(c2), aabb1.GetCenter(c1), displacement);

@@ -254,0 +321,0 @@ broadPhase.MoveProxy(proxy.treeNode, proxy.aabb, displacement);

@@ -11,6 +11,13 @@ import { b2Vec2, b2Mat22, XY } from "../common/b2_math";

}
/**
* Friction joint definition.
*/
export declare class b2FrictionJointDef extends b2JointDef implements b2IFrictionJointDef {
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The maximum friction force in N. */
maxForce: number;
/** The maximum friction torque in N-m. */
maxTorque: number;

@@ -20,22 +27,26 @@ constructor();

}
/**
* Friction joint. This is used for top-down friction.
* It provides 2D translational friction and angular friction.
*/
export declare class b2FrictionJoint extends b2Joint {
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
readonly m_linearImpulse: b2Vec2;
m_angularImpulse: number;
m_maxForce: number;
m_maxTorque: number;
m_indexA: number;
m_indexB: number;
readonly m_rA: b2Vec2;
readonly m_rB: b2Vec2;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
readonly m_linearMass: b2Mat22;
m_angularMass: number;
constructor(def: b2IFrictionJointDef);
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected readonly m_linearImpulse: b2Vec2;
protected m_angularImpulse: number;
protected m_maxForce: number;
protected m_maxTorque: number;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_rA: b2Vec2;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected readonly m_linearMass: b2Mat22;
protected m_angularMass: number;
protected constructor(def: b2IFrictionJointDef);
InitVelocityConstraints(data: b2SolverData): void;

@@ -42,0 +53,0 @@ SolveVelocityConstraints(data: b2SolverData): void;

@@ -32,9 +32,15 @@ "use strict";

};
/// Friction joint definition.
/**
* Friction joint definition.
*/
class b2FrictionJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_frictionJoint);
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2();
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2();
/** The maximum friction force in N. */
this.maxForce = 0;
/** The maximum friction torque in N-m. */
this.maxTorque = 0;

@@ -50,3 +56,8 @@ }

exports.b2FrictionJointDef = b2FrictionJointDef;
/**
* Friction joint. This is used for top-down friction.
* It provides 2D translational friction and angular friction.
*/
class b2FrictionJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -100,4 +111,4 @@ var _a, _b;

// Compute the effective mass matrix.
const rA = b2_math_1.b2Rot.MultiplyVec2(qA, b2_math_1.b2Vec2.Subtract(this.m_localAnchorA, this.m_localCenterA, lalcA), this.m_rA);
const rB = b2_math_1.b2Rot.MultiplyVec2(qB, b2_math_1.b2Vec2.Subtract(this.m_localAnchorB, this.m_localCenterB, lalcB), this.m_rB);
b2_math_1.b2Rot.MultiplyVec2(qA, b2_math_1.b2Vec2.Subtract(this.m_localAnchorA, this.m_localCenterA, lalcA), this.m_rA);
b2_math_1.b2Rot.MultiplyVec2(qB, b2_math_1.b2Vec2.Subtract(this.m_localAnchorB, this.m_localCenterB, lalcB), this.m_rB);
// J = [-I -r1_skew I r2_skew]

@@ -115,6 +126,6 @@ // [ 0 -1 0 1]

const K = this.m_linearMass;
K.ex.x = mA + mB + iA * rA.y * rA.y + iB * rB.y * rB.y;
K.ex.y = -iA * rA.x * rA.y - iB * rB.x * rB.y;
K.ex.x = mA + mB + iA * this.m_rA.y * this.m_rA.y + iB * this.m_rB.y * this.m_rB.y;
K.ex.y = -iA * this.m_rA.x * this.m_rA.y - iB * this.m_rB.x * this.m_rB.y;
K.ey.x = K.ex.y;
K.ey.y = mA + mB + iA * rA.x * rA.x + iB * rB.x * rB.x;
K.ey.y = mA + mB + iA * this.m_rA.x * this.m_rA.x + iB * this.m_rB.x * this.m_rB.x;
K.Inverse();

@@ -208,2 +219,3 @@ this.m_angularMass = iA + iB;

SetMaxForce(force) {
// DEBUG: b2Assert(Number.isFinite(force) && force >= 0);
this.m_maxForce = force;

@@ -215,2 +227,3 @@ }

SetMaxTorque(torque) {
// DEBUG: b2Assert(Number.isFinite(torque) && torque >= 0);
this.m_maxTorque = torque;

@@ -217,0 +230,0 @@ }

@@ -12,53 +12,78 @@ import { b2Vec2, XY } from "../common/b2_math";

}
/**
* Gear joint definition. This definition requires two existing
* revolute or prismatic joints (any combination will work).
*
* @warning bodyB on the input joints must both be dynamic
*/
export declare class b2GearJointDef extends b2JointDef implements b2IGearJointDef {
/** The first revolute/prismatic joint attached to the gear joint. */
joint1: b2RevoluteJoint | b2PrismaticJoint;
/** The second revolute/prismatic joint attached to the gear joint. */
joint2: b2RevoluteJoint | b2PrismaticJoint;
/**
* The gear ratio.
*
* @see b2GearJoint for explanation.
*/
ratio: number;
constructor();
}
/**
* A gear joint is used to connect two joints together. Either joint
* can be a revolute or prismatic joint. You specify a gear ratio
* to bind the motions together:
* coordinate1 + ratio * coordinate2 = constant
* The ratio can be negative or positive. If one joint is a revolute joint
* and the other joint is a prismatic joint, then the ratio will have units
* of length or units of 1/length.
*
* @warning You have to manually destroy the gear joint if joint1 or joint2
* is destroyed.
*/
export declare class b2GearJoint extends b2Joint {
m_joint1: b2RevoluteJoint | b2PrismaticJoint;
m_joint2: b2RevoluteJoint | b2PrismaticJoint;
m_typeA: b2JointType;
m_typeB: b2JointType;
m_bodyC: b2Body;
m_bodyD: b2Body;
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
readonly m_localAnchorC: b2Vec2;
readonly m_localAnchorD: b2Vec2;
readonly m_localAxisC: b2Vec2;
readonly m_localAxisD: b2Vec2;
m_referenceAngleA: number;
m_referenceAngleB: number;
m_constant: number;
m_ratio: number;
m_impulse: number;
m_indexA: number;
m_indexB: number;
m_indexC: number;
m_indexD: number;
readonly m_lcA: b2Vec2;
readonly m_lcB: b2Vec2;
readonly m_lcC: b2Vec2;
readonly m_lcD: b2Vec2;
m_mA: number;
m_mB: number;
m_mC: number;
m_mD: number;
m_iA: number;
m_iB: number;
m_iC: number;
m_iD: number;
readonly m_JvAC: b2Vec2;
readonly m_JvBD: b2Vec2;
m_JwA: number;
m_JwB: number;
m_JwC: number;
m_JwD: number;
m_mass: number;
constructor(def: b2IGearJointDef);
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(data: b2SolverData): boolean;
protected m_joint1: b2RevoluteJoint | b2PrismaticJoint;
protected m_joint2: b2RevoluteJoint | b2PrismaticJoint;
protected m_typeA: b2JointType;
protected m_typeB: b2JointType;
protected m_bodyC: b2Body;
protected m_bodyD: b2Body;
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected readonly m_localAnchorC: b2Vec2;
protected readonly m_localAnchorD: b2Vec2;
protected readonly m_localAxisC: b2Vec2;
protected readonly m_localAxisD: b2Vec2;
protected m_referenceAngleA: number;
protected m_referenceAngleB: number;
protected m_constant: number;
protected m_ratio: number;
protected m_impulse: number;
protected m_indexA: number;
protected m_indexB: number;
protected m_indexC: number;
protected m_indexD: number;
protected readonly m_lcA: b2Vec2;
protected readonly m_lcB: b2Vec2;
protected readonly m_lcC: b2Vec2;
protected readonly m_lcD: b2Vec2;
protected m_mA: number;
protected m_mB: number;
protected m_mC: number;
protected m_mD: number;
protected m_iA: number;
protected m_iB: number;
protected m_iC: number;
protected m_iD: number;
protected readonly m_JvAC: b2Vec2;
protected readonly m_JvBD: b2Vec2;
protected m_JwA: number;
protected m_JwB: number;
protected m_JwC: number;
protected m_JwD: number;
protected m_mass: number;
protected constructor(def: b2IGearJointDef);
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(data: b2SolverData): boolean;
GetAnchorA<T extends XY>(out: T): T;

@@ -65,0 +90,0 @@ GetAnchorB<T extends XY>(out: T): T;

@@ -42,10 +42,16 @@ "use strict";

};
/// Gear joint definition. This definition requires two existing
/// revolute or prismatic joints (any combination will work).
/// @warning bodyB on the input joints must both be dynamic
/**
* Gear joint definition. This definition requires two existing
* revolute or prismatic joints (any combination will work).
*
* @warning bodyB on the input joints must both be dynamic
*/
class b2GearJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_gearJoint);
/// The gear ratio.
/// @see b2GearJoint for explanation.
/**
* The gear ratio.
*
* @see b2GearJoint for explanation.
*/
this.ratio = 1;

@@ -55,12 +61,16 @@ }

exports.b2GearJointDef = b2GearJointDef;
/// A gear joint is used to connect two joints together. Either joint
/// can be a revolute or prismatic joint. You specify a gear ratio
/// to bind the motions together:
/// coordinate1 + ratio * coordinate2 = constant
/// The ratio can be negative or positive. If one joint is a revolute joint
/// and the other joint is a prismatic joint, then the ratio will have units
/// of length or units of 1/length.
/// @warning You have to manually destroy the gear joint if joint1 or joint2
/// is destroyed.
/**
* A gear joint is used to connect two joints together. Either joint
* can be a revolute or prismatic joint. You specify a gear ratio
* to bind the motions together:
* coordinate1 + ratio * coordinate2 = constant
* The ratio can be negative or positive. If one joint is a revolute joint
* and the other joint is a prismatic joint, then the ratio will have units
* of length or units of 1/length.
*
* @warning You have to manually destroy the gear joint if joint1 or joint2
* is destroyed.
*/
class b2GearJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -140,3 +150,3 @@ var _a;

const pC = this.m_localAnchorC;
const pA = b2_math_1.b2Rot.MultiplyVec2(xfC.q, b2_math_1.b2Rot.MultiplyVec2(xfA.q, this.m_localAnchorA, b2_math_1.b2Vec2.s_t0).Add(xfA.p).Subtract(xfC.p), b2_math_1.b2Vec2.s_t0);
const pA = b2_math_1.b2Rot.TransposeMultiplyVec2(xfC.q, b2_math_1.b2Rot.MultiplyVec2(xfA.q, this.m_localAnchorA, b2_math_1.b2Vec2.s_t0).Add(xfA.p).Subtract(xfC.p), b2_math_1.b2Vec2.s_t0);
coordinateA = b2_math_1.b2Vec2.Dot(pA.Subtract(pC), this.m_localAxisC);

@@ -146,2 +156,4 @@ }

this.m_bodyB = this.m_joint2.GetBodyB();
// Body B on joint2 must be dynamic
// DEBUG: b2Assert(this.m_bodyB.m_type === b2BodyType.b2_dynamicBody);
// Get geometry of joint2

@@ -174,2 +186,3 @@ const xfB = this.m_bodyB.m_xf;

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -266,2 +279,3 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -294,2 +308,3 @@ const vA = data.velocities[this.m_indexA].v;

}
/** @internal protected */
SolvePositionConstraints(data) {

@@ -349,3 +364,2 @@ const cA = data.positions[this.m_indexA].c;

b2_math_1.b2Rot.MultiplyVec2(qB, b2_math_1.b2Vec2.Subtract(this.m_localAnchorB, this.m_lcB, lalcB), rB);
b2_math_1.b2Rot.MultiplyVec2(qB, lalcB, rB);
b2_math_1.b2Vec2.Scale(this.m_ratio, u, JvBD);

@@ -352,0 +366,0 @@ JwD = this.m_ratio * b2_math_1.b2Vec2.Cross(rD, u);

@@ -7,31 +7,2 @@ import { b2Vec2 } from "../common/b2_math";

import { b2TimeStep, b2Profile, b2Position, b2Velocity } from "./b2_time_step";
import { b2ContactListener } from "./b2_world_callbacks";
export declare class b2Island {
m_listener: b2ContactListener;
readonly m_bodies: b2Body[];
readonly m_contacts: b2Contact[];
readonly m_joints: b2Joint[];
readonly m_positions: b2Position[];
readonly m_velocities: b2Velocity[];
m_bodyCount: number;
m_jointCount: number;
m_contactCount: number;
m_bodyCapacity: number;
m_contactCapacity: number;
m_jointCapacity: number;
Initialize(bodyCapacity: number, contactCapacity: number, jointCapacity: number, listener: b2ContactListener): void;
Clear(): void;
AddBody(body: b2Body): void;
AddContact(contact: b2Contact): void;
AddJoint(joint: b2Joint): void;
private static s_timer;
private static s_solverData;
private static s_contactSolverDef;
private static s_contactSolver;
private static s_translation;
Solve(profile: b2Profile, step: b2TimeStep, gravity: b2Vec2, allowSleep: boolean): void;
SolveTOI(subStep: b2TimeStep, toiIndexA: number, toiIndexB: number): void;
private static s_impulse;
Report(constraints: b2ContactVelocityConstraint[]): void;
}
//# sourceMappingURL=b2_island.d.ts.map
import { b2ContactListener } from "./b2_world_callbacks";

@@ -144,56 +144,23 @@ "use strict";

*/
/** @internal */
class b2Island {
constructor() {
this.m_bodies = [
/* 1024 */
]; // TODO: b2Settings
this.m_contacts = [
/* 1024 */
]; // TODO: b2Settings
this.m_joints = [
/* 1024 */
]; // TODO: b2Settings
this.m_positions = b2_time_step_1.b2Position.MakeArray(1024); // TODO: b2Settings
this.m_velocities = b2_time_step_1.b2Velocity.MakeArray(1024); // TODO: b2Settings
constructor(bodyCapacity, contactCapacity, jointCapacity, listener) {
this.m_bodyCount = 0;
this.m_jointCount = 0;
this.m_contactCount = 0;
this.m_bodyCapacity = 0;
this.m_contactCapacity = 0;
this.m_jointCapacity = 0;
}
Initialize(bodyCapacity, contactCapacity, jointCapacity, listener) {
this.m_bodyCapacity = bodyCapacity;
this.m_contactCapacity = contactCapacity;
this.m_jointCapacity = jointCapacity;
this.m_bodyCount = 0;
this.m_contactCount = 0;
this.m_jointCount = 0;
this.m_listener = listener;
// TODO:
// while (this.m_bodies.length < bodyCapacity) {
// this.m_bodies[this.m_bodies.length] = null;
// }
// TODO:
// while (this.m_contacts.length < contactCapacity) {
// this.m_contacts[this.m_contacts.length] = null;
// }
// TODO:
// while (this.m_joints.length < jointCapacity) {
// this.m_joints[this.m_joints.length] = null;
// }
// TODO:
if (this.m_positions.length < bodyCapacity) {
const new_length = Math.max(this.m_positions.length * 2, bodyCapacity);
while (this.m_positions.length < new_length) {
this.m_positions[this.m_positions.length] = new b2_time_step_1.b2Position();
}
this.m_bodies = new Array(bodyCapacity);
this.m_contacts = new Array(contactCapacity);
this.m_joints = new Array(jointCapacity);
this.m_velocities = b2_common_1.b2MakeArray(bodyCapacity, b2_time_step_1.b2Velocity);
this.m_positions = b2_common_1.b2MakeArray(bodyCapacity, b2_time_step_1.b2Position);
this.Resize(bodyCapacity);
}
Resize(bodyCapacity) {
while (this.m_bodyCapacity < bodyCapacity) {
this.m_velocities[this.m_bodyCapacity] = new b2_time_step_1.b2Velocity();
this.m_positions[this.m_bodyCapacity] = new b2_time_step_1.b2Position();
this.m_bodyCapacity++;
}
// TODO:
if (this.m_velocities.length < bodyCapacity) {
const new_length = Math.max(this.m_velocities.length * 2, bodyCapacity);
while (this.m_velocities.length < new_length) {
this.m_velocities[this.m_velocities.length] = new b2_time_step_1.b2Velocity();
}
}
}

@@ -208,10 +175,9 @@ Clear() {

body.m_islandIndex = this.m_bodyCount;
this.m_bodies[this.m_bodyCount++] = body;
this.m_bodies[this.m_bodyCount] = body;
++this.m_bodyCount;
}
AddContact(contact) {
// DEBUG: b2Assert(this.m_contactCount < this.m_contactCapacity);
this.m_contacts[this.m_contactCount++] = contact;
}
AddJoint(joint) {
// DEBUG: b2Assert(this.m_jointCount < this.m_jointCapacity);
this.m_joints[this.m_jointCount++] = joint;

@@ -301,4 +267,3 @@ }

// Integrate
c.x += h * v.x;
c.y += h * v.y;
c.AddScaled(h, v);
a += h * w;

@@ -468,5 +433,2 @@ this.m_positions[i].a = a;

Report(constraints) {
if (this.m_listener === null) {
return;
}
for (let i = 0; i < this.m_contactCount; ++i) {

@@ -473,0 +435,0 @@ const c = this.m_contacts[i];

@@ -0,1 +1,2 @@

import { b2Draw } from "../common/b2_draw";
import { XY } from "../common/b2_math";

@@ -18,27 +19,54 @@ import type { b2Body } from "./b2_body";

}
/**
* 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 b2JointEdge {
private m_other;
get other(): b2Body;
set other(value: b2Body);
/** Provides quick access to the other body attached. */
readonly other: b2Body;
/** The joint */
readonly joint: b2Joint;
/** The previous joint edge in the body's joint list */
prev: b2JointEdge | null;
/** The next joint edge in the body's joint list */
next: b2JointEdge | null;
constructor(joint: b2Joint);
Reset(): void;
constructor(joint: b2Joint, other: b2Body);
}
/**
* Joint definitions are used to construct joints.
*/
export interface b2IJointDef {
/** The joint type is set automatically for concrete joint types. */
type: b2JointType;
/** Use this to attach application specific data to your joints. */
userData?: any;
/** The first attached body. */
bodyA: b2Body;
/** The second attached body. */
bodyB: b2Body;
/** Set this flag to true if the attached bodies should collide. */
collideConnected?: boolean;
}
/**
* Joint definitions are used to construct joints.
*/
export declare abstract class b2JointDef implements b2IJointDef {
/** The joint type is set automatically for concrete joint types. */
readonly type: b2JointType;
/** Use this to attach application specific data to your joints. */
userData: any;
/** The first attached body. */
bodyA: b2Body;
/** The second attached body. */
bodyB: b2Body;
/** Set this flag to true if the attached bodies should collide. */
collideConnected: boolean;
constructor(type: b2JointType);
}
/**
* Utility to compute linear stiffness values from frequency and damping ratio
*/
export declare function b2LinearStiffness(def: {

@@ -48,2 +76,5 @@ stiffness: number;

}, frequencyHertz: number, dampingRatio: number, bodyA: b2Body, bodyB: b2Body): void;
/**
* Utility to compute rotational stiffness values frequency and damping ratio
*/
export declare function b2AngularStiffness(def: {

@@ -53,32 +84,80 @@ stiffness: number;

}, frequencyHertz: number, dampingRatio: number, bodyA: b2Body, bodyB: b2Body): void;
/**
* 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 b2Joint {
readonly m_type: b2JointType;
m_prev: b2Joint | null;
m_next: b2Joint | null;
readonly m_edgeA: b2JointEdge;
readonly m_edgeB: b2JointEdge;
m_bodyA: b2Body;
m_bodyB: b2Body;
m_index: number;
m_islandFlag: boolean;
m_collideConnected: boolean;
m_userData: any;
constructor(def: b2IJointDef);
protected readonly m_type: b2JointType;
protected m_prev: b2Joint | null;
protected m_next: b2Joint | null;
protected readonly m_edgeA: b2JointEdge;
protected readonly m_edgeB: b2JointEdge;
protected m_bodyA: b2Body;
protected m_bodyB: b2Body;
protected m_islandFlag: boolean;
protected m_collideConnected: boolean;
protected m_userData: any;
protected constructor(def: b2IJointDef);
/**
* Get the type of the concrete joint.
*/
GetType(): b2JointType;
/**
* Get the first body attached to this joint.
*/
GetBodyA(): b2Body;
/**
* Get the second body attached to this joint.
*/
GetBodyB(): b2Body;
/**
* Get the anchor point on bodyA in world coordinates.
*/
abstract GetAnchorA<T extends XY>(out: T): T;
/**
* Get the anchor point on bodyB in world coordinates.
*/
abstract GetAnchorB<T extends XY>(out: T): T;
/**
* Get the reaction force on bodyB at the joint anchor in Newtons.
*/
abstract GetReactionForce<T extends XY>(inv_dt: number, out: T): T;
/**
* Get the reaction torque on bodyB in N*m.
*/
abstract GetReactionTorque(inv_dt: number): number;
/**
* Get the next joint the world joint list.
*/
GetNext(): b2Joint | null;
/**
* Get the user data pointer.
*/
GetUserData(): any;
/**
* Set the user data pointer.
*/
SetUserData(data: any): void;
/**
* Short-cut function to determine if either body is inactive.
*/
IsEnabled(): boolean;
/**
* 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;
/**
* Shift the origin for any points stored in world coordinates.
*/
ShiftOrigin(_newOrigin: XY): void;
abstract InitVelocityConstraints(data: b2SolverData): void;
abstract SolveVelocityConstraints(data: b2SolverData): void;
abstract SolvePositionConstraints(data: b2SolverData): boolean;
protected abstract InitVelocityConstraints(data: b2SolverData): void;
protected abstract SolveVelocityConstraints(data: b2SolverData): void;
/**
* This returns true if the position errors are within tolerance.
*/
protected abstract SolvePositionConstraints(data: b2SolverData): boolean;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_joint.d.ts.map

@@ -21,3 +21,9 @@ "use strict";

exports.b2Joint = exports.b2AngularStiffness = exports.b2LinearStiffness = exports.b2JointDef = exports.b2JointEdge = exports.b2JointType = void 0;
const b2_common_1 = require("../common/b2_common");
// DEBUG: import { b2Assert } from "../common/b2_common";
const b2_draw_1 = require("../common/b2_draw");
const b2_math_1 = require("../common/b2_math");
const temp = {
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
};
var b2JointType;

@@ -38,35 +44,28 @@ (function (b2JointType) {

})(b2JointType = exports.b2JointType || (exports.b2JointType = {}));
/// 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.
/**
* 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.
*/
class b2JointEdge {
constructor(joint) {
this.m_other = null; /// < provides quick access to the other body attached.
this.prev = null; /// < the previous joint edge in the body's joint list
this.next = null; /// < the next joint edge in the body's joint list
this.joint = joint;
}
get other() {
b2_common_1.b2Assert(this.m_other !== null);
return this.m_other;
}
set other(value) {
b2_common_1.b2Assert(this.m_other === null);
this.m_other = value;
}
Reset() {
this.m_other = null;
constructor(joint, other) {
/** The previous joint edge in the body's joint list */
this.prev = null;
/** The next joint edge in the body's joint list */
this.next = null;
this.joint = joint;
this.other = other;
}
}
exports.b2JointEdge = b2JointEdge;
/// Joint definitions are used to construct joints.
/**
* Joint definitions are used to construct joints.
*/
class b2JointDef {
constructor(type) {
/// Use this to attach application specific data to your joints.
/** Use this to attach application specific data to your joints. */
this.userData = null;
/// Set this flag to true if the attached bodies should collide.
/** Set this flag to true if the attached bodies should collide. */
this.collideConnected = false;

@@ -77,3 +76,5 @@ this.type = type;

exports.b2JointDef = b2JointDef;
/// Utility to compute linear stiffness values from frequency and damping ratio
/**
* Utility to compute linear stiffness values from frequency and damping ratio
*/
// void b2LinearStiffness(float& stiffness, float& damping,

@@ -100,6 +101,5 @@ // float frequencyHertz, float dampingRatio,

exports.b2LinearStiffness = b2LinearStiffness;
/// Utility to compute rotational stiffness values frequency and damping ratio
// void b2AngularStiffness(float& stiffness, float& damping,
// float frequencyHertz, float dampingRatio,
// const b2Body* bodyA, const b2Body* bodyB);
/**
* Utility to compute rotational stiffness values frequency and damping ratio
*/
function b2AngularStiffness(def, frequencyHertz, dampingRatio, bodyA, bodyB) {

@@ -109,3 +109,3 @@ const IA = bodyA.GetInertia();

let I;
if (IA > 0.0 && IB > 0) {
if (IA > 0 && IB > 0) {
I = (IA * IB) / (IA + IB);

@@ -124,4 +124,6 @@ }

exports.b2AngularStiffness = b2AngularStiffness;
/// The base joint class. Joints are used to constraint two bodies together in
/// various fashions. Some joints also feature limits and motors.
/**
* The base joint class. Joints are used to constraint two bodies together in
* various fashions. Some joints also feature limits and motors.
*/
class b2Joint {

@@ -132,13 +134,14 @@ constructor(def) {

this.m_type = b2JointType.e_unknownJoint;
/** @internal protected */
this.m_prev = null;
/** @internal protected */
this.m_next = null;
this.m_edgeA = new b2JointEdge(this);
this.m_edgeB = new b2JointEdge(this);
this.m_index = 0;
/** @internal protected */
this.m_islandFlag = false;
/** @internal protected */
this.m_collideConnected = false;
this.m_userData = null;
this.m_type = def.type;
this.m_edgeA.other = def.bodyB; // nope
this.m_edgeB.other = def.bodyA; // nope
this.m_edgeA = new b2JointEdge(this, def.bodyB);
this.m_edgeB = new b2JointEdge(this, def.bodyA);
this.m_bodyA = def.bodyA;

@@ -149,39 +152,66 @@ this.m_bodyB = def.bodyB;

}
/// Get the type of the concrete joint.
/**
* Get the type of the concrete joint.
*/
GetType() {
return this.m_type;
}
/// Get the first body attached to this joint.
/**
* Get the first body attached to this joint.
*/
GetBodyA() {
return this.m_bodyA;
}
/// Get the second body attached to this joint.
/**
* Get the second body attached to this joint.
*/
GetBodyB() {
return this.m_bodyB;
}
/// Get the next joint the world joint list.
/**
* Get the next joint the world joint list.
*/
GetNext() {
return this.m_next;
}
/// Get the user data pointer.
/**
* Get the user data pointer.
*/
GetUserData() {
return this.m_userData;
}
/// Set the user data pointer.
/**
* Set the user data pointer.
*/
SetUserData(data) {
this.m_userData = data;
}
/// Short-cut function to determine if either body is inactive.
/**
* Short-cut function to determine if either body is inactive.
*/
IsEnabled() {
return this.m_bodyA.IsEnabled() && this.m_bodyB.IsEnabled();
}
/// 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.
/**
* 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() {
return this.m_collideConnected;
}
/// Shift the origin for any points stored in world coordinates.
/**
* Shift the origin for any points stored in world coordinates.
*/
ShiftOrigin(_newOrigin) { }
Draw(draw) {
const x1 = this.m_bodyA.GetTransform().p;
const x2 = this.m_bodyB.GetTransform().p;
const p1 = this.GetAnchorA(temp.pA);
const p2 = this.GetAnchorB(temp.pB);
draw.DrawSegment(x1, p1, b2_draw_1.debugColors.joint6);
draw.DrawSegment(p1, p2, b2_draw_1.debugColors.joint6);
draw.DrawSegment(x2, p2, b2_draw_1.debugColors.joint6);
}
}
exports.b2Joint = b2Joint;

@@ -12,7 +12,15 @@ import { b2Vec2, b2Mat22, XY } from "../common/b2_math";

}
/**
* Motor joint definition.
*/
export declare class b2MotorJointDef extends b2JointDef implements b2IMotorJointDef {
/** Position of bodyB minus the position of bodyA, in bodyA's frame, in meters. */
readonly linearOffset: b2Vec2;
/** The bodyB angle minus bodyA angle in radians. */
angularOffset: number;
/** The maximum motor force in N. */
maxForce: number;
/** The maximum motor torque in N-m. */
maxTorque: number;
/** Position correction factor in the range [0,1]. */
correctionFactor: number;

@@ -22,25 +30,30 @@ constructor();

}
/**
* A motor joint is used to control the relative motion
* between two bodies. A typical usage is to control the movement
* of a dynamic body with respect to the ground.
*/
export declare class b2MotorJoint extends b2Joint {
readonly m_linearOffset: b2Vec2;
m_angularOffset: number;
readonly m_linearImpulse: b2Vec2;
m_angularImpulse: number;
m_maxForce: number;
m_maxTorque: number;
m_correctionFactor: number;
m_indexA: number;
m_indexB: number;
readonly m_rA: b2Vec2;
readonly m_rB: b2Vec2;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
readonly m_linearError: b2Vec2;
m_angularError: number;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
readonly m_linearMass: b2Mat22;
m_angularMass: number;
constructor(def: b2IMotorJointDef);
protected readonly m_linearOffset: b2Vec2;
protected m_angularOffset: number;
protected readonly m_linearImpulse: b2Vec2;
protected m_angularImpulse: number;
protected m_maxForce: number;
protected m_maxTorque: number;
protected m_correctionFactor: number;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_rA: b2Vec2;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected readonly m_linearError: b2Vec2;
protected m_angularError: number;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected readonly m_linearMass: b2Mat22;
protected m_angularMass: number;
protected constructor(def: b2IMotorJointDef);
GetAnchorA<T extends XY>(out: T): T;

@@ -58,6 +71,8 @@ GetAnchorB<T extends XY>(out: T): T;

GetMaxTorque(): number;
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(_data: b2SolverData): boolean;
GetCorrectionFactor(): number;
SetCorrectionFactor(factor: number): void;
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(_data: b2SolverData): boolean;
}
//# sourceMappingURL=b2_motor_joint.d.ts.map

@@ -45,15 +45,17 @@ "use strict";

};
/// Motor joint definition.
/**
* Motor joint definition.
*/
class b2MotorJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_motorJoint);
/// Position of bodyB minus the position of bodyA, in bodyA's frame, in meters.
/** Position of bodyB minus the position of bodyA, in bodyA's frame, in meters. */
this.linearOffset = new b2_math_1.b2Vec2();
/// The bodyB angle minus bodyA angle in radians.
/** The bodyB angle minus bodyA angle in radians. */
this.angularOffset = 0;
/// The maximum motor force in N.
/** The maximum motor force in N. */
this.maxForce = 1;
/// The maximum motor torque in N-m.
/** The maximum motor torque in N-m. */
this.maxTorque = 1;
/// Position correction factor in the range [0,1].
/** Position correction factor in the range [0,1]. */
this.correctionFactor = 0.3;

@@ -71,6 +73,9 @@ }

exports.b2MotorJointDef = b2MotorJointDef;
/// A motor joint is used to control the relative motion
/// between two bodies. A typical usage is to control the movement
/// of a dynamic body with respect to the ground.
/**
* A motor joint is used to control the relative motion
* between two bodies. A typical usage is to control the movement
* of a dynamic body with respect to the ground.
*/
class b2MotorJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -101,4 +106,4 @@ var _a, _b, _c, _d, _e;

this.m_linearImpulse.SetZero();
this.m_maxForce = (_c = def.maxForce) !== null && _c !== void 0 ? _c : 0;
this.m_maxTorque = (_d = def.maxTorque) !== null && _d !== void 0 ? _d : 0;
this.m_maxForce = (_c = def.maxForce) !== null && _c !== void 0 ? _c : 1;
this.m_maxTorque = (_d = def.maxTorque) !== null && _d !== void 0 ? _d : 1;
this.m_correctionFactor = (_e = def.correctionFactor) !== null && _e !== void 0 ? _e : 0.3;

@@ -158,2 +163,10 @@ }

}
GetCorrectionFactor() {
return this.m_correctionFactor;
}
SetCorrectionFactor(factor) {
// DEBUG: b2Assert(Number.isFinite(factor) && factor >= 0 && factor <= 1);
this.m_correctionFactor = factor;
}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -222,2 +235,3 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -248,5 +262,3 @@ const vA = data.velocities[this.m_indexA].v;

const { impulse, oldImpulse, Cdot } = temp;
const rA = this.m_rA;
const rB = this.m_rB;
b2_math_1.b2Vec2.AddScaled(b2_math_1.b2Vec2.Subtract(b2_math_1.b2Vec2.AddCrossScalarVec2(vB, wB, rB, b2_math_1.b2Vec2.s_t0), b2_math_1.b2Vec2.AddCrossScalarVec2(vA, wA, rA, b2_math_1.b2Vec2.s_t1), b2_math_1.b2Vec2.s_t2), inv_h * this.m_correctionFactor, this.m_linearError, Cdot);
b2_math_1.b2Vec2.AddScaled(b2_math_1.b2Vec2.Subtract(b2_math_1.b2Vec2.AddCrossScalarVec2(vB, wB, this.m_rB, b2_math_1.b2Vec2.s_t0), b2_math_1.b2Vec2.AddCrossScalarVec2(vA, wA, this.m_rA, b2_math_1.b2Vec2.s_t1), b2_math_1.b2Vec2.s_t2), inv_h * this.m_correctionFactor, this.m_linearError, Cdot);
b2_math_1.b2Mat22.MultiplyVec2(this.m_linearMass, Cdot, impulse).Negate();

@@ -262,5 +274,5 @@ oldImpulse.Copy(this.m_linearImpulse);

vA.SubtractScaled(mA, impulse);
wA -= iA * b2_math_1.b2Vec2.Cross(rA, impulse);
wA -= iA * b2_math_1.b2Vec2.Cross(this.m_rA, impulse);
vB.AddScaled(mB, impulse);
wB += iB * b2_math_1.b2Vec2.Cross(rB, impulse);
wB += iB * b2_math_1.b2Vec2.Cross(this.m_rB, impulse);
}

@@ -270,2 +282,3 @@ data.velocities[this.m_indexA].w = wA;

}
/** @internal protected */
SolvePositionConstraints(_data) {

@@ -272,0 +285,0 @@ return true;

@@ -0,1 +1,2 @@

import { b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Mat22, XY } from "../common/b2_math";

@@ -10,27 +11,50 @@ import { b2Joint, b2JointDef, b2IJointDef } from "./b2_joint";

}
/**
* Mouse joint definition. This requires a world target point,
* tuning parameters, and the time step.
*/
export declare class b2MouseJointDef extends b2JointDef implements b2IMouseJointDef {
/**
* The initial world target point. This is assumed
* to coincide with the body anchor initially.
*/
readonly target: b2Vec2;
/**
* The maximum constraint force that can be exerted
* to move the candidate body. Usually you will express
* as some multiple of the weight (multiplier * mass * gravity).
*/
maxForce: number;
/** The linear stiffness in N/m */
stiffness: number;
/** The linear damping in N*s/m */
damping: number;
constructor();
}
/**
* A mouse joint is used to make a point on a body track a
* specified world point. This a soft constraint with a maximum
* force. This allows the constraint to stretch and without
* applying huge forces.
* NOTE: this joint is not documented in the manual because it was
* developed to be used in the testbed. If you want to learn how to
* use the mouse joint, look at the testbed.
*/
export declare class b2MouseJoint extends b2Joint {
readonly m_localAnchorB: b2Vec2;
readonly m_targetA: b2Vec2;
m_stiffness: number;
m_damping: number;
m_beta: number;
readonly m_impulse: b2Vec2;
m_maxForce: number;
m_gamma: number;
m_indexA: number;
m_indexB: number;
readonly m_rB: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassB: number;
m_invIB: number;
readonly m_mass: b2Mat22;
readonly m_C: b2Vec2;
constructor(def: b2IMouseJointDef);
protected readonly m_localAnchorB: b2Vec2;
protected readonly m_targetA: b2Vec2;
protected m_stiffness: number;
protected m_damping: number;
protected m_beta: number;
protected readonly m_impulse: b2Vec2;
protected m_maxForce: number;
protected m_gamma: number;
protected m_indexB: number;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassB: number;
protected m_invIB: number;
protected readonly m_mass: b2Mat22;
protected readonly m_C: b2Vec2;
protected constructor(def: b2IMouseJointDef);
SetTarget(target: XY): void;

@@ -44,5 +68,5 @@ GetTarget(): b2Vec2;

GetDamping(): number;
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(_data: b2SolverData): boolean;
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(_data: b2SolverData): boolean;
GetAnchorA<T extends XY>(out: T): T;

@@ -53,3 +77,4 @@ GetAnchorB<T extends XY>(out: T): T;

ShiftOrigin(newOrigin: XY): void;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_mouse_joint.d.ts.map

@@ -22,2 +22,3 @@ "use strict";

// DEBUG: import { b2Assert, b2_epsilon } from "../common/b2_common";
const b2_draw_1 = require("../common/b2_draw");
const b2_math_1 = require("../common/b2_math");

@@ -31,18 +32,26 @@ const b2_joint_1 = require("./b2_joint");

oldImpulse: new b2_math_1.b2Vec2(),
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
};
/// Mouse joint definition. This requires a world target point,
/// tuning parameters, and the time step.
/**
* Mouse joint definition. This requires a world target point,
* tuning parameters, and the time step.
*/
class b2MouseJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_mouseJoint);
/// The initial world target point. This is assumed
/// to coincide with the body anchor initially.
/**
* The initial world target point. This is assumed
* to coincide with the body anchor initially.
*/
this.target = new b2_math_1.b2Vec2();
/// The maximum constraint force that can be exerted
/// to move the candidate body. Usually you will express
/// as some multiple of the weight (multiplier * mass * gravity).
/**
* The maximum constraint force that can be exerted
* to move the candidate body. Usually you will express
* as some multiple of the weight (multiplier * mass * gravity).
*/
this.maxForce = 0;
/// The linear stiffness in N/m
/** The linear stiffness in N/m */
this.stiffness = 0;
/// The linear damping in N*s/m
/** The linear damping in N*s/m */
this.damping = 0;

@@ -52,10 +61,13 @@ }

exports.b2MouseJointDef = b2MouseJointDef;
/// A mouse joint is used to make a point on a body track a
/// specified world point. This a soft constraint with a maximum
/// force. This allows the constraint to stretch and without
/// applying huge forces.
/// NOTE: this joint is not documented in the manual because it was
/// developed to be used in the testbed. If you want to learn how to
/// use the mouse joint, look at the testbed.
/**
* A mouse joint is used to make a point on a body track a
* specified world point. This a soft constraint with a maximum
* force. This allows the constraint to stretch and without
* applying huge forces.
* NOTE: this joint is not documented in the manual because it was
* developed to be used in the testbed. If you want to learn how to
* use the mouse joint, look at the testbed.
*/
class b2MouseJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -74,3 +86,2 @@ var _a, _b, _c, _d;

// Solver temp
this.m_indexA = 0;
this.m_indexB = 0;

@@ -118,2 +129,3 @@ this.m_rB = new b2_math_1.b2Vec2();

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -166,2 +178,3 @@ this.m_indexB = this.m_bodyB.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -185,2 +198,3 @@ const vB = data.velocities[this.m_indexB].v;

}
/** @internal protected */
SolvePositionConstraints(_data) {

@@ -206,3 +220,10 @@ return true;

}
Draw(draw) {
const p1 = this.GetAnchorA(temp.pA);
const p2 = this.GetAnchorB(temp.pB);
draw.DrawPoint(p1, 4, b2_draw_1.debugColors.joint7);
draw.DrawPoint(p2, 4, b2_draw_1.debugColors.joint7);
draw.DrawSegment(p1, p2, b2_draw_1.debugColors.joint8);
}
}
exports.b2MouseJoint = b2MouseJoint;

@@ -5,6 +5,2 @@ import { b2Transform } from "../common/b2_math";

import { b2PolygonShape } from "../collision/b2_polygon_shape";
import { b2Contact } from "./b2_contact";
export declare class b2PolygonAndCircleContact extends b2Contact<b2PolygonShape, b2CircleShape> {
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_polygon_circle_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -23,2 +23,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2PolygonAndCircleContact extends b2_contact_1.b2Contact {

@@ -25,0 +26,0 @@ Evaluate(manifold, xfA, xfB) {

import { b2Transform } from "../common/b2_math";
import { b2Manifold } from "../collision/b2_collision";
import { b2PolygonShape } from "../collision/b2_polygon_shape";
import { b2Contact } from "./b2_contact";
export declare class b2PolygonContact extends b2Contact<b2PolygonShape, b2PolygonShape> {
Evaluate(manifold: b2Manifold, xfA: b2Transform, xfB: b2Transform): void;
}
//# sourceMappingURL=b2_polygon_contact.d.ts.map
import { b2Contact } from "./b2_contact";

@@ -23,2 +23,3 @@ "use strict";

const b2_contact_1 = require("./b2_contact");
/** @internal */
class b2PolygonContact extends b2_contact_1.b2Contact {

@@ -25,0 +26,0 @@ Evaluate(manifold, xfA, xfB) {

@@ -0,1 +1,2 @@

import { b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Mat22, XY } from "../common/b2_math";

@@ -17,12 +18,30 @@ import { b2Body } from "./b2_body";

}
/**
* Prismatic joint definition. This requires defining a line of
* motion using an axis and an anchor point. The definition uses local
* anchor points and a local axis so that the initial configuration
* can violate the constraint slightly. The joint translation is zero
* when the local anchor points coincide in world space. Using local
* anchors and a local axis helps when saving and loading a game.
*/
export declare class b2PrismaticJointDef extends b2JointDef implements b2IPrismaticJointDef {
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The local translation unit axis in bodyA. */
readonly localAxisA: b2Vec2;
/** The constrained angle between the bodies: bodyB_angle - bodyA_angle. */
referenceAngle: number;
/** Enable/disable the joint limit. */
enableLimit: boolean;
/** The lower translation limit, usually in meters. */
lowerTranslation: number;
/** The upper translation limit, usually in meters. */
upperTranslation: number;
/** Enable/disable the joint motor. */
enableMotor: boolean;
/** The maximum motor torque, usually in N-m. */
maxMotorForce: number;
/** The desired motor speed in radians per second. */
motorSpeed: number;

@@ -32,39 +51,54 @@ constructor();

}
/**
* A prismatic joint. This joint provides one degree of freedom: translation
* along an axis fixed in bodyA. Relative rotation is prevented. You can
* use a joint limit to restrict the range of motion and a joint motor to
* drive the motion or to model joint friction.
*/
export declare class b2PrismaticJoint extends b2Joint {
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
readonly m_localXAxisA: b2Vec2;
readonly m_localYAxisA: b2Vec2;
m_referenceAngle: number;
readonly m_impulse: b2Vec2;
m_motorImpulse: number;
m_lowerImpulse: number;
m_upperImpulse: number;
m_lowerTranslation: number;
m_upperTranslation: number;
m_maxMotorForce: number;
m_motorSpeed: number;
m_enableLimit: boolean;
m_enableMotor: boolean;
m_indexA: number;
m_indexB: number;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
readonly m_axis: b2Vec2;
readonly m_perp: b2Vec2;
m_s1: number;
m_s2: number;
m_a1: number;
m_a2: number;
readonly m_K: b2Mat22;
m_translation: number;
m_axialMass: number;
constructor(def: b2IPrismaticJointDef);
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(data: b2SolverData): boolean;
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected readonly m_localXAxisA: b2Vec2;
protected readonly m_localYAxisA: b2Vec2;
protected m_referenceAngle: number;
protected readonly m_impulse: b2Vec2;
protected m_motorImpulse: number;
protected m_lowerImpulse: number;
protected m_upperImpulse: number;
protected m_lowerTranslation: number;
protected m_upperTranslation: number;
protected m_maxMotorForce: number;
protected m_motorSpeed: number;
protected m_enableLimit: boolean;
protected m_enableMotor: boolean;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected readonly m_axis: b2Vec2;
protected readonly m_perp: b2Vec2;
protected m_s1: number;
protected m_s2: number;
protected m_a1: number;
protected m_a2: number;
protected readonly m_K: b2Mat22;
protected m_translation: number;
protected m_axialMass: number;
protected constructor(def: b2IPrismaticJointDef);
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
/**
* A velocity based solver computes reaction forces(impulses) using the velocity constraint solver.Under this context,
* the position solver is not there to resolve forces.It is only there to cope with integration error.
*
* Therefore, the pseudo impulses in the position solver do not have any physical meaning.Thus it is okay if they suck.
*
* We could take the active state from the velocity solver.However, the joint might push past the limit when the velocity
* solver indicates the limit is inactive.
*/
protected SolvePositionConstraints(data: b2SolverData): boolean;
GetAnchorA<T extends XY>(out: T): T;

@@ -81,3 +115,3 @@ GetAnchorB<T extends XY>(out: T): T;

IsLimitEnabled(): boolean;
EnableLimit(flag: boolean): void;
EnableLimit(flag: boolean): boolean;
GetLowerLimit(): number;

@@ -87,4 +121,4 @@ GetUpperLimit(): number;

IsMotorEnabled(): boolean;
EnableMotor(flag: boolean): void;
SetMotorSpeed(speed: number): void;
EnableMotor(flag: boolean): boolean;
SetMotorSpeed(speed: number): number;
GetMotorSpeed(): number;

@@ -94,3 +128,4 @@ SetMaxMotorForce(force: number): void;

GetMotorForce(inv_dt: number): number;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_prismatic_joint.d.ts.map

@@ -22,2 +22,3 @@ "use strict";

const b2_common_1 = require("../common/b2_common");
const b2_draw_1 = require("../common/b2_draw");
const b2_math_1 = require("../common/b2_math");

@@ -54,31 +55,43 @@ const b2_joint_1 = require("./b2_joint");

},
Draw: {
p1: new b2_math_1.b2Vec2(),
p2: new b2_math_1.b2Vec2(),
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
axis: new b2_math_1.b2Vec2(),
lower: new b2_math_1.b2Vec2(),
upper: new b2_math_1.b2Vec2(),
perp: new b2_math_1.b2Vec2(),
},
};
/// Prismatic joint definition. This requires defining a line of
/// motion using an axis and an anchor point. The definition uses local
/// anchor points and a local axis so that the initial configuration
/// can violate the constraint slightly. The joint translation is zero
/// when the local anchor points coincide in world space. Using local
/// anchors and a local axis helps when saving and loading a game.
/**
* Prismatic joint definition. This requires defining a line of
* motion using an axis and an anchor point. The definition uses local
* anchor points and a local axis so that the initial configuration
* can violate the constraint slightly. The joint translation is zero
* when the local anchor points coincide in world space. Using local
* anchors and a local axis helps when saving and loading a game.
*/
class b2PrismaticJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_prismaticJoint);
/// The local anchor point relative to bodyA's origin.
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2();
/// The local anchor point relative to bodyB's origin.
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2();
/// The local translation unit axis in bodyA.
/** The local translation unit axis in bodyA. */
this.localAxisA = new b2_math_1.b2Vec2(1, 0);
/// The constrained angle between the bodies: bodyB_angle - bodyA_angle.
/** The constrained angle between the bodies: bodyB_angle - bodyA_angle. */
this.referenceAngle = 0;
/// Enable/disable the joint limit.
/** Enable/disable the joint limit. */
this.enableLimit = false;
/// The lower translation limit, usually in meters.
/** The lower translation limit, usually in meters. */
this.lowerTranslation = 0;
/// The upper translation limit, usually in meters.
/** The upper translation limit, usually in meters. */
this.upperTranslation = 0;
/// Enable/disable the joint motor.
/** Enable/disable the joint motor. */
this.enableMotor = false;
/// The maximum motor torque, usually in N-m.
/** The maximum motor torque, usually in N-m. */
this.maxMotorForce = 0;
/// The desired motor speed in radians per second.
/** The desired motor speed in radians per second. */
this.motorSpeed = 0;

@@ -137,14 +150,21 @@ }

// a1 = cross(d + r1, v), a2 = cross(r2, v)
/// A prismatic joint. This joint provides one degree of freedom: translation
/// along an axis fixed in bodyA. Relative rotation is prevented. You can
/// use a joint limit to restrict the range of motion and a joint motor to
/// drive the motion or to model joint friction.
/**
* A prismatic joint. This joint provides one degree of freedom: translation
* along an axis fixed in bodyA. Relative rotation is prevented. You can
* use a joint limit to restrict the range of motion and a joint motor to
* drive the motion or to model joint friction.
*/
class b2PrismaticJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
super(def);
/** @internal protected */
this.m_localAnchorA = new b2_math_1.b2Vec2();
/** @internal protected */
this.m_localAnchorB = new b2_math_1.b2Vec2();
/** @internal protected */
this.m_localXAxisA = new b2_math_1.b2Vec2();
this.m_localYAxisA = new b2_math_1.b2Vec2();
/** @internal protected */
this.m_referenceAngle = 0;

@@ -181,3 +201,3 @@ this.m_impulse = new b2_math_1.b2Vec2();

this.m_localAnchorB.Copy((_b = def.localAnchorB) !== null && _b !== void 0 ? _b : b2_math_1.b2Vec2.ZERO);
this.m_localXAxisA.Copy((_c = def.localAxisA) !== null && _c !== void 0 ? _c : b2_math_1.b2Vec2.UNITX).Normalize();
b2_math_1.b2Vec2.Normalize((_c = def.localAxisA) !== null && _c !== void 0 ? _c : b2_math_1.b2Vec2.UNITX, this.m_localXAxisA);
b2_math_1.b2Vec2.CrossOneVec2(this.m_localXAxisA, this.m_localYAxisA);

@@ -193,2 +213,3 @@ this.m_referenceAngle = (_d = def.referenceAngle) !== null && _d !== void 0 ? _d : 0;

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -278,2 +299,3 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -358,9 +380,13 @@ const vA = data.velocities[this.m_indexA].v;

}
// A velocity based solver computes reaction forces(impulses) using the velocity constraint solver.Under this context,
// the position solver is not there to resolve forces.It is only there to cope with integration error.
//
// Therefore, the pseudo impulses in the position solver do not have any physical meaning.Thus it is okay if they suck.
//
// We could take the active state from the velocity solver.However, the joint might push past the limit when the velocity
// solver indicates the limit is inactive.
/**
* A velocity based solver computes reaction forces(impulses) using the velocity constraint solver.Under this context,
* the position solver is not there to resolve forces.It is only there to cope with integration error.
*
* Therefore, the pseudo impulses in the position solver do not have any physical meaning.Thus it is okay if they suck.
*
* We could take the active state from the velocity solver.However, the joint might push past the limit when the velocity
* solver indicates the limit is inactive.
*
* @internal protected
*/
SolvePositionConstraints(data) {

@@ -419,2 +445,3 @@ const cA = data.positions[this.m_indexA].c;

if (k22 === 0) {
// For fixed rotation
k22 = 1;

@@ -498,5 +525,5 @@ }

b2_math_1.b2Rot.MultiplyVec2(bB.m_xf.q, b2_math_1.b2Vec2.Subtract(this.m_localAnchorB, bB.m_sweep.localCenter, lalcB), rB);
const pA = b2_math_1.b2Vec2.Add(bA.m_sweep.c, rA, b2_math_1.b2Vec2.s_t0);
const pB = b2_math_1.b2Vec2.Add(bB.m_sweep.c, rB, b2_math_1.b2Vec2.s_t1);
const d = b2_math_1.b2Vec2.Subtract(pB, pA, b2_math_1.b2Vec2.s_t2);
const p1 = b2_math_1.b2Vec2.Add(bA.m_sweep.c, rA, b2_math_1.b2Vec2.s_t0);
const p2 = b2_math_1.b2Vec2.Add(bB.m_sweep.c, rB, b2_math_1.b2Vec2.s_t1);
const d = b2_math_1.b2Vec2.Subtract(p2, p1, b2_math_1.b2Vec2.s_t2);
const axis = b2_math_1.b2Rot.MultiplyVec2(bA.m_xf.q, this.m_localXAxisA, this.m_axis);

@@ -522,2 +549,3 @@ const vA = bA.m_linearVelocity;

}
return flag;
}

@@ -550,2 +578,3 @@ GetLowerLimit() {

}
return flag;
}

@@ -558,2 +587,3 @@ SetMotorSpeed(speed) {

}
return speed;
}

@@ -576,3 +606,26 @@ GetMotorSpeed() {

}
Draw(draw) {
const { p1, p2, pA, pB, axis } = temp.Draw;
const xfA = this.m_bodyA.GetTransform();
const xfB = this.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, this.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, this.m_localAnchorB, pB);
b2_math_1.b2Rot.MultiplyVec2(xfA.q, this.m_localXAxisA, axis);
draw.DrawSegment(pA, pB, b2_draw_1.debugColors.joint5);
if (this.m_enableLimit) {
const { lower, upper, perp } = temp.Draw;
b2_math_1.b2Vec2.AddScaled(pA, this.m_lowerTranslation, axis, lower);
b2_math_1.b2Vec2.AddScaled(pA, this.m_upperTranslation, axis, upper);
b2_math_1.b2Rot.MultiplyVec2(xfA.q, this.m_localYAxisA, perp);
draw.DrawSegment(lower, upper, b2_draw_1.debugColors.joint1);
draw.DrawSegment(b2_math_1.b2Vec2.SubtractScaled(lower, 0.5, perp, p1), b2_math_1.b2Vec2.AddScaled(lower, 0.5, perp, p2), b2_draw_1.debugColors.joint2);
draw.DrawSegment(b2_math_1.b2Vec2.SubtractScaled(upper, 0.5, perp, p1), b2_math_1.b2Vec2.AddScaled(upper, 0.5, perp, p2), b2_draw_1.debugColors.joint3);
}
else {
draw.DrawSegment(b2_math_1.b2Vec2.Subtract(pA, axis, p1), b2_math_1.b2Vec2.Add(pA, axis, p2), b2_draw_1.debugColors.joint1);
}
draw.DrawPoint(pA, 5, b2_draw_1.debugColors.joint1);
draw.DrawPoint(pB, 5, b2_draw_1.debugColors.joint4);
}
}
exports.b2PrismaticJoint = b2PrismaticJoint;

@@ -0,1 +1,2 @@

import { b2Draw } from "../common/b2_draw";
import { b2Vec2, XY } from "../common/b2_math";

@@ -15,9 +16,20 @@ import { b2Body } from "./b2_body";

}
/**
* Pulley joint definition. This requires two ground anchors,
* two dynamic body anchor points, and a pulley ratio.
*/
export declare class b2PulleyJointDef extends b2JointDef implements b2IPulleyJointDef {
/** The first ground anchor in world coordinates. This point never moves. */
readonly groundAnchorA: b2Vec2;
/** The second ground anchor in world coordinates. This point never moves. */
readonly groundAnchorB: b2Vec2;
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The a reference length for the segment attached to bodyA. */
lengthA: number;
/** The a reference length for the segment attached to bodyB. */
lengthB: number;
/** The pulley ratio, used to simulate a block-and-tackle. */
ratio: number;

@@ -27,29 +39,39 @@ constructor();

}
/**
* The pulley joint is connected to two bodies and two fixed ground points.
* The pulley supports a ratio such that:
* length1 + ratio * length2 <= constant
* Yes, the force transmitted is scaled by the ratio.
* Warning: the pulley joint can get a bit squirrelly by itself. They often
* work better when combined with prismatic joints. You should also cover the
* the anchor points with static shapes to prevent one side from going to
* zero length.
*/
export declare class b2PulleyJoint extends b2Joint {
readonly m_groundAnchorA: b2Vec2;
readonly m_groundAnchorB: b2Vec2;
m_lengthA: number;
m_lengthB: number;
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
m_constant: number;
m_ratio: number;
m_impulse: number;
m_indexA: number;
m_indexB: number;
readonly m_uA: b2Vec2;
readonly m_uB: b2Vec2;
readonly m_rA: b2Vec2;
readonly m_rB: b2Vec2;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
m_mass: number;
constructor(def: b2IPulleyJointDef);
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(data: b2SolverData): boolean;
protected readonly m_groundAnchorA: b2Vec2;
protected readonly m_groundAnchorB: b2Vec2;
protected m_lengthA: number;
protected m_lengthB: number;
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected m_constant: number;
protected m_ratio: number;
protected m_impulse: number;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_uA: b2Vec2;
protected readonly m_uB: b2Vec2;
protected readonly m_rA: b2Vec2;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected m_mass: number;
protected constructor(def: b2IPulleyJointDef);
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(data: b2SolverData): boolean;
GetAnchorA<T extends XY>(out: T): T;

@@ -67,3 +89,4 @@ GetAnchorB<T extends XY>(out: T): T;

ShiftOrigin(newOrigin: b2Vec2): void;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_pulley_joint.d.ts.map

@@ -23,2 +23,3 @@ "use strict";

const b2_common_1 = require("../common/b2_common");
const b2_draw_1 = require("../common/b2_draw");
const b2_math_1 = require("../common/b2_math");

@@ -37,21 +38,25 @@ const b2_joint_1 = require("./b2_joint");

vpB: new b2_math_1.b2Vec2(),
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
};
/// Pulley joint definition. This requires two ground anchors,
/// two dynamic body anchor points, and a pulley ratio.
/**
* Pulley joint definition. This requires two ground anchors,
* two dynamic body anchor points, and a pulley ratio.
*/
class b2PulleyJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_pulleyJoint);
/// The first ground anchor in world coordinates. This point never moves.
/** The first ground anchor in world coordinates. This point never moves. */
this.groundAnchorA = new b2_math_1.b2Vec2(-1, 1);
/// The second ground anchor in world coordinates. This point never moves.
/** The second ground anchor in world coordinates. This point never moves. */
this.groundAnchorB = new b2_math_1.b2Vec2(1, 1);
/// The local anchor point relative to bodyA's origin.
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2(-1, 0);
/// The local anchor point relative to bodyB's origin.
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2(1, 0);
/// The a reference length for the segment attached to bodyA.
/** The a reference length for the segment attached to bodyA. */
this.lengthA = 0;
/// The a reference length for the segment attached to bodyB.
/** The a reference length for the segment attached to bodyB. */
this.lengthB = 0;
/// The pulley ratio, used to simulate a block-and-tackle.
/** The pulley ratio, used to simulate a block-and-tackle. */
this.ratio = 1;

@@ -78,11 +83,14 @@ this.collideConnected = true;

const defaultLocalAnchorB = b2_math_1.b2Vec2.UNITX;
/// The pulley joint is connected to two bodies and two fixed ground points.
/// The pulley supports a ratio such that:
/// length1 + ratio * length2 <= constant
/// Yes, the force transmitted is scaled by the ratio.
/// Warning: the pulley joint can get a bit squirrelly by itself. They often
/// work better when combined with prismatic joints. You should also cover the
/// the anchor points with static shapes to prevent one side from going to
/// zero length.
/**
* The pulley joint is connected to two bodies and two fixed ground points.
* The pulley supports a ratio such that:
* length1 + ratio * length2 <= constant
* Yes, the force transmitted is scaled by the ratio.
* Warning: the pulley joint can get a bit squirrelly by itself. They often
* work better when combined with prismatic joints. You should also cover the
* the anchor points with static shapes to prevent one side from going to
* zero length.
*/
class b2PulleyJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -126,2 +134,3 @@ var _a, _b, _c, _d, _e, _f, _g;

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -193,2 +202,3 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -214,2 +224,3 @@ const vA = data.velocities[this.m_indexA].v;

}
/** @internal protected */
SolvePositionConstraints(data) {

@@ -307,3 +318,12 @@ const cA = data.positions[this.m_indexA].c;

}
Draw(draw) {
const p1 = this.GetAnchorA(temp.pA);
const p2 = this.GetAnchorB(temp.pB);
const s1 = this.GetGroundAnchorA();
const s2 = this.GetGroundAnchorB();
draw.DrawSegment(s1, p1, b2_draw_1.debugColors.joint6);
draw.DrawSegment(s2, p2, b2_draw_1.debugColors.joint6);
draw.DrawSegment(s1, s2, b2_draw_1.debugColors.joint6);
}
}
exports.b2PulleyJoint = b2PulleyJoint;

@@ -0,1 +1,2 @@

import { b2Draw } from "../common/b2_draw";
import { b2Vec2, b2Mat22, XY } from "../common/b2_math";

@@ -16,11 +17,35 @@ import { b2Body } from "./b2_body";

}
/**
* Revolute joint definition. This requires defining an anchor point where the
* bodies are joined. The definition uses local anchor points so that the
* initial configuration can violate the constraint slightly. You also need to
* specify the initial relative angle for joint limits. This helps when saving
* and loading a game.
* The local anchor points are measured from the body's origin
* rather than the center of mass because:
* 1. you might not know where the center of mass will be.
* 2. if you add/remove shapes from a body and recompute the mass,
* the joints will be broken.
*/
export declare class b2RevoluteJointDef extends b2JointDef implements b2IRevoluteJointDef {
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The bodyB angle minus bodyA angle in the reference state (radians). */
referenceAngle: number;
/** A flag to enable joint limits. */
enableLimit: boolean;
/** The lower angle for the joint limit (radians). */
lowerAngle: number;
/** The upper angle for the joint limit (radians). */
upperAngle: number;
/** A flag to enable the joint motor. */
enableMotor: boolean;
/** The desired motor speed. Usually in radians per second. */
motorSpeed: number;
/**
* The maximum motor torque used to achieve the desired motor speed.
* Usually in N-m.
*/
maxMotorTorque: number;

@@ -30,30 +55,38 @@ constructor();

}
/**
* A revolute joint constrains two bodies to share a common point while they
* are free to rotate about the point. The relative rotation about the shared
* point is the joint angle. You can limit the relative rotation with
* a joint limit that specifies a lower and upper angle. You can use a motor
* to drive the relative rotation about the shared point. A maximum motor torque
* is provided so that infinite forces are not generated.
*/
export declare class b2RevoluteJoint extends b2Joint {
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
readonly m_impulse: b2Vec2;
m_motorImpulse: number;
m_lowerImpulse: number;
m_upperImpulse: number;
m_enableMotor: boolean;
m_maxMotorTorque: number;
m_motorSpeed: number;
m_enableLimit: boolean;
m_referenceAngle: number;
m_lowerAngle: number;
m_upperAngle: number;
m_indexA: number;
m_indexB: number;
readonly m_rA: b2Vec2;
readonly m_rB: b2Vec2;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
readonly m_K: b2Mat22;
m_angle: number;
m_axialMass: number;
constructor(def: b2IRevoluteJointDef);
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected readonly m_impulse: b2Vec2;
protected m_motorImpulse: number;
protected m_lowerImpulse: number;
protected m_upperImpulse: number;
protected m_enableMotor: boolean;
protected m_maxMotorTorque: number;
protected m_motorSpeed: number;
protected m_enableLimit: boolean;
protected m_referenceAngle: number;
protected m_lowerAngle: number;
protected m_upperAngle: number;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_rA: b2Vec2;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected readonly m_K: b2Mat22;
protected m_angle: number;
protected m_axialMass: number;
protected constructor(def: b2IRevoluteJointDef);
InitVelocityConstraints(data: b2SolverData): void;

@@ -72,3 +105,3 @@ SolveVelocityConstraints(data: b2SolverData): void;

IsMotorEnabled(): boolean;
EnableMotor(flag: boolean): void;
EnableMotor(flag: boolean): boolean;
GetMotorTorque(inv_dt: number): number;

@@ -79,8 +112,9 @@ GetMotorSpeed(): number;

IsLimitEnabled(): boolean;
EnableLimit(flag: boolean): void;
EnableLimit(flag: boolean): boolean;
GetLowerLimit(): number;
GetUpperLimit(): number;
SetLimits(lower: number, upper: number): void;
SetMotorSpeed(speed: number): void;
SetMotorSpeed(speed: number): number;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_revolute_joint.d.ts.map

@@ -22,2 +22,3 @@ "use strict";

const b2_common_1 = require("../common/b2_common");
const b2_draw_1 = require("../common/b2_draw");
const b2_math_1 = require("../common/b2_math");

@@ -34,34 +35,44 @@ const b2_joint_1 = require("./b2_joint");

impulse: new b2_math_1.b2Vec2(),
p2: new b2_math_1.b2Vec2(),
r: new b2_math_1.b2Vec2(),
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
rlo: new b2_math_1.b2Vec2(),
rhi: new b2_math_1.b2Vec2(),
};
/// Revolute joint definition. This requires defining an anchor point where the
/// bodies are joined. The definition uses local anchor points so that the
/// initial configuration can violate the constraint slightly. You also need to
/// specify the initial relative angle for joint limits. This helps when saving
/// and loading a game.
/// The local anchor points are measured from the body's origin
/// rather than the center of mass because:
/// 1. you might not know where the center of mass will be.
/// 2. if you add/remove shapes from a body and recompute the mass,
/// the joints will be broken.
/**
* Revolute joint definition. This requires defining an anchor point where the
* bodies are joined. The definition uses local anchor points so that the
* initial configuration can violate the constraint slightly. You also need to
* specify the initial relative angle for joint limits. This helps when saving
* and loading a game.
* The local anchor points are measured from the body's origin
* rather than the center of mass because:
* 1. you might not know where the center of mass will be.
* 2. if you add/remove shapes from a body and recompute the mass,
* the joints will be broken.
*/
class b2RevoluteJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_revoluteJoint);
/// The local anchor point relative to bodyA's origin.
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2();
/// The local anchor point relative to bodyB's origin.
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2();
/// The bodyB angle minus bodyA angle in the reference state (radians).
/** The bodyB angle minus bodyA angle in the reference state (radians). */
this.referenceAngle = 0;
/// A flag to enable joint limits.
/** A flag to enable joint limits. */
this.enableLimit = false;
/// The lower angle for the joint limit (radians).
/** The lower angle for the joint limit (radians). */
this.lowerAngle = 0;
/// The upper angle for the joint limit (radians).
/** The upper angle for the joint limit (radians). */
this.upperAngle = 0;
/// A flag to enable the joint motor.
/** A flag to enable the joint motor. */
this.enableMotor = false;
/// The desired motor speed. Usually in radians per second.
/** The desired motor speed. Usually in radians per second. */
this.motorSpeed = 0;
/// The maximum motor torque used to achieve the desired motor speed.
/// Usually in N-m.
/**
* The maximum motor torque used to achieve the desired motor speed.
* Usually in N-m.
*/
this.maxMotorTorque = 0;

@@ -78,9 +89,12 @@ }

exports.b2RevoluteJointDef = b2RevoluteJointDef;
/// A revolute joint constrains two bodies to share a common point while they
/// are free to rotate about the point. The relative rotation about the shared
/// point is the joint angle. You can limit the relative rotation with
/// a joint limit that specifies a lower and upper angle. You can use a motor
/// to drive the relative rotation about the shared point. A maximum motor torque
/// is provided so that infinite forces are not generated.
/**
* A revolute joint constrains two bodies to share a common point while they
* are free to rotate about the point. The relative rotation about the shared
* point is the joint angle. You can limit the relative rotation with
* a joint limit that specifies a lower and upper angle. You can use a motor
* to drive the relative rotation about the shared point. A maximum motor torque
* is provided so that infinite forces are not generated.
*/
class b2RevoluteJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -90,3 +104,5 @@ var _a, _b, _c, _d, _e, _f, _g, _h, _j;

// Solver shared
/** @internal protected */
this.m_localAnchorA = new b2_math_1.b2Vec2();
/** @internal protected */
this.m_localAnchorB = new b2_math_1.b2Vec2();

@@ -101,2 +117,3 @@ this.m_impulse = new b2_math_1.b2Vec2();

this.m_enableLimit = false;
/** @internal protected */
this.m_referenceAngle = 0;

@@ -279,3 +296,3 @@ this.m_lowerAngle = 0;

const angle = aB - aA - this.m_referenceAngle;
let C = 0.0;
let C = 0;
if (Math.abs(this.m_upperAngle - this.m_lowerAngle) < 2 * b2_common_1.b2_angularSlop) {

@@ -363,2 +380,3 @@ // Prevent large angular corrections

}
return flag;
}

@@ -392,2 +410,3 @@ GetMotorTorque(inv_dt) {

}
return flag;
}

@@ -416,4 +435,31 @@ GetLowerLimit() {

}
return speed;
}
Draw(draw) {
const { p2, r, pA, pB } = temp;
const xfA = this.m_bodyA.GetTransform();
const xfB = this.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, this.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, this.m_localAnchorB, pB);
draw.DrawPoint(pA, 5, b2_draw_1.debugColors.joint4);
draw.DrawPoint(pB, 5, b2_draw_1.debugColors.joint5);
const aA = this.m_bodyA.GetAngle();
const aB = this.m_bodyB.GetAngle();
const angle = aB - aA - this.m_referenceAngle;
const L = 0.5;
r.Set(Math.cos(angle), Math.sin(angle)).Scale(L);
draw.DrawSegment(pB, b2_math_1.b2Vec2.Add(pB, r, p2), b2_draw_1.debugColors.joint1);
draw.DrawCircle(pB, L, b2_draw_1.debugColors.joint1);
if (this.m_enableLimit) {
const { rlo, rhi } = temp;
rlo.Set(Math.cos(this.m_lowerAngle), Math.sin(this.m_lowerAngle)).Scale(L);
rhi.Set(Math.cos(this.m_upperAngle), Math.sin(this.m_upperAngle)).Scale(L);
draw.DrawSegment(pB, b2_math_1.b2Vec2.Add(pB, rlo, p2), b2_draw_1.debugColors.joint2);
draw.DrawSegment(pB, b2_math_1.b2Vec2.Add(pB, rhi, p2), b2_draw_1.debugColors.joint3);
}
draw.DrawSegment(xfA.p, pA, b2_draw_1.debugColors.joint6);
draw.DrawSegment(pA, pB, b2_draw_1.debugColors.joint6);
draw.DrawSegment(xfB.p, pB, b2_draw_1.debugColors.joint6);
}
}
exports.b2RevoluteJoint = b2RevoluteJoint;
import { b2Vec2 } from "../common/b2_math";
/**
* Profiling data. Times are in milliseconds.
*/
export declare class b2Profile {

@@ -17,2 +20,5 @@ step: number;

}
/**
* This is an internal structure.
*/
export declare class b2TimeStep {

@@ -28,12 +34,19 @@ dt: number;

}
/**
* This is an internal structure.
*/
export declare class b2Position {
readonly c: b2Vec2;
a: number;
static MakeArray(length: number): b2Position[];
}
/**
* This is an internal structure.
*/
export declare class b2Velocity {
readonly v: b2Vec2;
w: number;
static MakeArray(length: number): b2Velocity[];
}
/**
* Solver Data
*/
export declare class b2SolverData {

@@ -40,0 +53,0 @@ readonly step: b2TimeStep;

@@ -22,3 +22,5 @@ "use strict";

const b2_math_1 = require("../common/b2_math");
/// Profiling data. Times are in milliseconds.
/**
* Profiling data. Times are in milliseconds.
*/
class b2Profile {

@@ -48,3 +50,5 @@ constructor() {

exports.b2Profile = b2Profile;
/// This is an internal structure.
/**
* This is an internal structure.
*/
class b2TimeStep {

@@ -76,3 +80,5 @@ constructor() {

exports.b2TimeStep = b2TimeStep;
/// This is an internal structure.
/**
* This is an internal structure.
*/
class b2Position {

@@ -83,11 +89,7 @@ constructor() {

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2Position();
return result;
}
}
exports.b2Position = b2Position;
/// This is an internal structure.
/**
* This is an internal structure.
*/
class b2Velocity {

@@ -98,11 +100,7 @@ constructor() {

}
static MakeArray(length) {
const result = new Array(length);
for (let i = 0; i < length; i++)
result[i] = new b2Velocity();
return result;
}
}
exports.b2Velocity = b2Velocity;
/// Solver Data
/**
* Solver Data
*/
class b2SolverData {

@@ -109,0 +107,0 @@ constructor() {

@@ -12,7 +12,20 @@ import { b2Vec2, b2Vec3, b2Mat33, XY } from "../common/b2_math";

}
/**
* Weld joint definition. You need to specify local anchor points
* where they are attached and the relative body angle. The position
* of the anchor points is important for computing the reaction torque.
*/
export declare class b2WeldJointDef extends b2JointDef implements b2IWeldJointDef {
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The bodyB angle minus bodyA angle in the reference state (radians). */
referenceAngle: number;
/**
* The rotational stiffness in N*m
* Disable softness with a value of 0
*/
stiffness: number;
/** The rotational damping in N*m*s */
damping: number;

@@ -22,26 +35,30 @@ constructor();

}
/**
* A weld joint essentially glues two bodies together. A weld joint may
* distort somewhat because the island constraint solver is approximate.
*/
export declare class b2WeldJoint extends b2Joint {
m_stiffness: number;
m_damping: number;
m_bias: number;
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
m_referenceAngle: number;
m_gamma: number;
readonly m_impulse: b2Vec3;
m_indexA: number;
m_indexB: number;
readonly m_rA: b2Vec2;
readonly m_rB: b2Vec2;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
readonly m_mass: b2Mat33;
constructor(def: b2IWeldJointDef);
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(data: b2SolverData): boolean;
protected m_stiffness: number;
protected m_damping: number;
protected m_bias: number;
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected m_referenceAngle: number;
protected m_gamma: number;
protected readonly m_impulse: b2Vec3;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_rA: b2Vec2;
protected readonly m_rB: b2Vec2;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected readonly m_mass: b2Mat33;
protected constructor(def: b2IWeldJointDef);
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(data: b2SolverData): boolean;
GetAnchorA<T extends XY>(out: T): T;

@@ -48,0 +65,0 @@ GetAnchorB<T extends XY>(out: T): T;

@@ -39,18 +39,22 @@ "use strict";

};
/// Weld joint definition. You need to specify local anchor points
/// where they are attached and the relative body angle. The position
/// of the anchor points is important for computing the reaction torque.
/**
* Weld joint definition. You need to specify local anchor points
* where they are attached and the relative body angle. The position
* of the anchor points is important for computing the reaction torque.
*/
class b2WeldJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_weldJoint);
/// The local anchor point relative to bodyA's origin.
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2();
/// The local anchor point relative to bodyB's origin.
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2();
/// The bodyB angle minus bodyA angle in the reference state (radians).
/** The bodyB angle minus bodyA angle in the reference state (radians). */
this.referenceAngle = 0;
/// The rotational stiffness in N*m
/// Disable softness with a value of 0
/**
* The rotational stiffness in N*m
* Disable softness with a value of 0
*/
this.stiffness = 0;
/// The rotational damping in N*m*s
/** The rotational damping in N*m*s */
this.damping = 0;

@@ -67,5 +71,8 @@ }

exports.b2WeldJointDef = b2WeldJointDef;
/// A weld joint essentially glues two bodies together. A weld joint may
/// distort somewhat because the island constraint solver is approximate.
/**
* A weld joint essentially glues two bodies together. A weld joint may
* distort somewhat because the island constraint solver is approximate.
*/
class b2WeldJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -101,2 +108,3 @@ var _a, _b, _c, _d, _e;

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -184,2 +192,3 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -226,2 +235,3 @@ const vA = data.velocities[this.m_indexA].v;

}
/** @internal protected */
SolvePositionConstraints(data) {

@@ -228,0 +238,0 @@ const cA = data.positions[this.m_indexA].c;

@@ -5,26 +5,57 @@ import { b2Vec2, XY } from "../common/b2_math";

import { b2Body } from "./b2_body";
import { b2Draw } from "../common/b2_draw";
export interface b2IWheelJointDef extends b2IJointDef {
/** The local anchor point relative to bodyA's origin. */
localAnchorA?: XY;
/** The local anchor point relative to bodyB's origin. */
localAnchorB?: XY;
/** The local translation axis in bodyA. */
localAxisA?: XY;
/** Enable/disable the joint limit. */
enableLimit?: boolean;
/** The lower translation limit, usually in meters. */
lowerTranslation?: number;
/** The upper translation limit, usually in meters. */
upperTranslation?: number;
/** Enable/disable the joint motor. */
enableMotor?: boolean;
/** The maximum motor torque, usually in N-m. */
maxMotorTorque?: number;
/** The desired motor speed in radians per second. */
motorSpeed?: number;
/** Suspension stiffness. Typically in units N/m. */
stiffness?: number;
/** Suspension damping. Typically in units of N*s/m. */
damping?: number;
}
/**
* Wheel joint definition. This requires defining a line of
* motion using an axis and an anchor point. The definition uses local
* anchor points and a local axis so that the initial configuration
* can violate the constraint slightly. The joint translation is zero
* when the local anchor points coincide in world space. Using local
* anchors and a local axis helps when saving and loading a game.
*/
export declare class b2WheelJointDef extends b2JointDef implements b2IWheelJointDef {
/** The local anchor point relative to bodyA's origin. */
readonly localAnchorA: b2Vec2;
/** The local anchor point relative to bodyB's origin. */
readonly localAnchorB: b2Vec2;
/** The local translation axis in bodyA. */
readonly localAxisA: b2Vec2;
/** Enable/disable the joint limit. */
enableLimit: boolean;
/** The lower translation limit, usually in meters. */
lowerTranslation: number;
/** The upper translation limit, usually in meters. */
upperTranslation: number;
/** Enable/disable the joint motor. */
enableMotor: boolean;
/** The maximum motor torque, usually in N-m. */
maxMotorTorque: number;
/** The desired motor speed in radians per second. */
motorSpeed: number;
/** Suspension stiffness. Typically in units N/m. */
stiffness: number;
/** Suspension damping. Typically in units of N*s/m. */
damping: number;

@@ -34,42 +65,48 @@ constructor();

}
/**
* A wheel joint. This joint provides two degrees of freedom: translation
* along an axis fixed in bodyA and rotation in the plane. In other words, it is a point to
* line constraint with a rotational motor and a linear spring/damper. The spring/damper is
* initialized upon creation. This joint is designed for vehicle suspensions.
*/
export declare class b2WheelJoint extends b2Joint {
readonly m_localAnchorA: b2Vec2;
readonly m_localAnchorB: b2Vec2;
readonly m_localXAxisA: b2Vec2;
readonly m_localYAxisA: b2Vec2;
m_impulse: number;
m_motorImpulse: number;
m_springImpulse: number;
m_lowerImpulse: number;
m_upperImpulse: number;
m_translation: number;
m_lowerTranslation: number;
m_upperTranslation: number;
m_maxMotorTorque: number;
m_motorSpeed: number;
m_enableLimit: boolean;
m_enableMotor: boolean;
m_stiffness: number;
m_damping: number;
m_indexA: number;
m_indexB: number;
readonly m_localCenterA: b2Vec2;
readonly m_localCenterB: b2Vec2;
m_invMassA: number;
m_invMassB: number;
m_invIA: number;
m_invIB: number;
readonly m_ax: b2Vec2;
readonly m_ay: b2Vec2;
m_sAx: number;
m_sBx: number;
m_sAy: number;
m_sBy: number;
m_mass: number;
m_motorMass: number;
m_axialMass: number;
m_springMass: number;
m_bias: number;
m_gamma: number;
constructor(def: b2IWheelJointDef);
protected readonly m_localAnchorA: b2Vec2;
protected readonly m_localAnchorB: b2Vec2;
protected readonly m_localXAxisA: b2Vec2;
protected readonly m_localYAxisA: b2Vec2;
protected m_impulse: number;
protected m_motorImpulse: number;
protected m_springImpulse: number;
protected m_lowerImpulse: number;
protected m_upperImpulse: number;
protected m_translation: number;
protected m_lowerTranslation: number;
protected m_upperTranslation: number;
protected m_maxMotorTorque: number;
protected m_motorSpeed: number;
protected m_enableLimit: boolean;
protected m_enableMotor: boolean;
protected m_stiffness: number;
protected m_damping: number;
protected m_indexA: number;
protected m_indexB: number;
protected readonly m_localCenterA: b2Vec2;
protected readonly m_localCenterB: b2Vec2;
protected m_invMassA: number;
protected m_invMassB: number;
protected m_invIA: number;
protected m_invIB: number;
protected readonly m_ax: b2Vec2;
protected readonly m_ay: b2Vec2;
protected m_sAx: number;
protected m_sBx: number;
protected m_sAy: number;
protected m_sBy: number;
protected m_mass: number;
protected m_motorMass: number;
protected m_axialMass: number;
protected m_springMass: number;
protected m_bias: number;
protected m_gamma: number;
protected constructor(def: b2IWheelJointDef);
GetMotorSpeed(): number;

@@ -81,5 +118,5 @@ GetMaxMotorTorque(): number;

GetDamping(): number;
InitVelocityConstraints(data: b2SolverData): void;
SolveVelocityConstraints(data: b2SolverData): void;
SolvePositionConstraints(data: b2SolverData): boolean;
protected InitVelocityConstraints(data: b2SolverData): void;
protected SolveVelocityConstraints(data: b2SolverData): void;
protected SolvePositionConstraints(data: b2SolverData): boolean;
GetAnchorA<T extends XY>(out: T): T;

@@ -97,12 +134,28 @@ GetAnchorB<T extends XY>(out: T): T;

IsMotorEnabled(): boolean;
EnableMotor(flag: boolean): void;
SetMotorSpeed(speed: number): void;
EnableMotor(flag: boolean): boolean;
SetMotorSpeed(speed: number): number;
SetMaxMotorTorque(torque: number): void;
GetMotorTorque(inv_dt: number): number;
/**
* Is the joint limit enabled?
*/
IsLimitEnabled(): boolean;
EnableLimit(flag: boolean): void;
/**
* Enable/disable the joint translation limit.
*/
EnableLimit(flag: boolean): boolean;
/**
* Get the lower joint translation limit, usually in meters.
*/
GetLowerLimit(): number;
/**
* Get the upper joint translation limit, usually in meters.
*/
GetUpperLimit(): number;
/**
* Set the joint translation limits, usually in meters.
*/
SetLimits(lower: number, upper: number): void;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_wheel_joint.d.ts.map

@@ -25,2 +25,3 @@ "use strict";

const b2_joint_1 = require("./b2_joint");
const b2_draw_1 = require("../common/b2_draw");
const temp = {

@@ -39,33 +40,45 @@ qA: new b2_math_1.b2Rot(),

axis: new b2_math_1.b2Vec2(),
Draw: {
p1: new b2_math_1.b2Vec2(),
p2: new b2_math_1.b2Vec2(),
pA: new b2_math_1.b2Vec2(),
pB: new b2_math_1.b2Vec2(),
axis: new b2_math_1.b2Vec2(),
lower: new b2_math_1.b2Vec2(),
upper: new b2_math_1.b2Vec2(),
perp: new b2_math_1.b2Vec2(),
},
};
/// Wheel joint definition. This requires defining a line of
/// motion using an axis and an anchor point. The definition uses local
/// anchor points and a local axis so that the initial configuration
/// can violate the constraint slightly. The joint translation is zero
/// when the local anchor points coincide in world space. Using local
/// anchors and a local axis helps when saving and loading a game.
/**
* Wheel joint definition. This requires defining a line of
* motion using an axis and an anchor point. The definition uses local
* anchor points and a local axis so that the initial configuration
* can violate the constraint slightly. The joint translation is zero
* when the local anchor points coincide in world space. Using local
* anchors and a local axis helps when saving and loading a game.
*/
class b2WheelJointDef extends b2_joint_1.b2JointDef {
constructor() {
super(b2_joint_1.b2JointType.e_wheelJoint);
/// The local anchor point relative to bodyA's origin.
/** The local anchor point relative to bodyA's origin. */
this.localAnchorA = new b2_math_1.b2Vec2();
/// The local anchor point relative to bodyB's origin.
/** The local anchor point relative to bodyB's origin. */
this.localAnchorB = new b2_math_1.b2Vec2();
/// The local translation axis in bodyA.
/** The local translation axis in bodyA. */
this.localAxisA = new b2_math_1.b2Vec2(1, 0);
/// Enable/disable the joint limit.
/** Enable/disable the joint limit. */
this.enableLimit = false;
/// The lower translation limit, usually in meters.
/** The lower translation limit, usually in meters. */
this.lowerTranslation = 0;
/// The upper translation limit, usually in meters.
/** The upper translation limit, usually in meters. */
this.upperTranslation = 0;
/// Enable/disable the joint motor.
/** Enable/disable the joint motor. */
this.enableMotor = false;
/// The maximum motor torque, usually in N-m.
/** The maximum motor torque, usually in N-m. */
this.maxMotorTorque = 0;
/// The desired motor speed in radians per second.
/** The desired motor speed in radians per second. */
this.motorSpeed = 0;
/// Suspension stiffness. Typically in units N/m.
/** Suspension stiffness. Typically in units N/m. */
this.stiffness = 0;
/// Suspension damping. Typically in units of N*s/m.
/** Suspension damping. Typically in units of N*s/m. */
this.damping = 0;

@@ -82,7 +95,10 @@ }

exports.b2WheelJointDef = b2WheelJointDef;
/// A wheel joint. This joint provides two degrees of freedom: translation
/// along an axis fixed in bodyA and rotation in the plane. In other words, it is a point to
/// line constraint with a rotational motor and a linear spring/damper. The spring/damper is
/// initialized upon creation. This joint is designed for vehicle suspensions.
/**
* A wheel joint. This joint provides two degrees of freedom: translation
* along an axis fixed in bodyA and rotation in the plane. In other words, it is a point to
* line constraint with a rotational motor and a linear spring/damper. The spring/damper is
* initialized upon creation. This joint is designed for vehicle suspensions.
*/
class b2WheelJoint extends b2_joint_1.b2Joint {
/** @internal protected */
constructor(def) {

@@ -163,2 +179,3 @@ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;

}
/** @internal protected */
InitVelocityConstraints(data) {

@@ -205,7 +222,7 @@ this.m_indexA = this.m_bodyA.m_islandIndex;

const invMass = mA + mB + iA * this.m_sAx * this.m_sAx + iB * this.m_sBx * this.m_sBx;
if (invMass > 0.0) {
this.m_axialMass = 1.0 / invMass;
if (invMass > 0) {
this.m_axialMass = 1 / invMass;
}
else {
this.m_axialMass = 0.0;
this.m_axialMass = 0;
}

@@ -275,2 +292,3 @@ this.m_springMass = 0;

}
/** @internal protected */
SolveVelocityConstraints(data) {

@@ -362,2 +380,3 @@ const mA = this.m_invMassA;

}
/** @internal protected */
SolvePositionConstraints(data) {

@@ -368,3 +387,3 @@ const cA = data.positions[this.m_indexA].c;

let aB = data.positions[this.m_indexB].a;
let linearError = 0.0;
let linearError = 0;
const { qA, qB, lalcA, lalcB, rA, rB, d, P, ay } = temp;

@@ -512,2 +531,3 @@ if (this.m_enableLimit) {

}
return flag;
}

@@ -520,2 +540,3 @@ SetMotorSpeed(speed) {

}
return speed;
}

@@ -532,7 +553,11 @@ SetMaxMotorTorque(torque) {

}
/// Is the joint limit enabled?
/**
* Is the joint limit enabled?
*/
IsLimitEnabled() {
return this.m_enableLimit;
}
/// Enable/disable the joint translation limit.
/**
* Enable/disable the joint translation limit.
*/
EnableLimit(flag) {

@@ -543,15 +568,22 @@ if (flag !== this.m_enableLimit) {

this.m_enableLimit = flag;
this.m_lowerImpulse = 0.0;
this.m_upperImpulse = 0.0;
this.m_lowerImpulse = 0;
this.m_upperImpulse = 0;
}
return flag;
}
/// Get the lower joint translation limit, usually in meters.
/**
* Get the lower joint translation limit, usually in meters.
*/
GetLowerLimit() {
return this.m_lowerTranslation;
}
/// Get the upper joint translation limit, usually in meters.
/**
* Get the upper joint translation limit, usually in meters.
*/
GetUpperLimit() {
return this.m_upperTranslation;
}
/// Set the joint translation limits, usually in meters.
/**
* Set the joint translation limits, usually in meters.
*/
SetLimits(lower, upper) {

@@ -568,3 +600,26 @@ // b2Assert(lower <= upper);

}
Draw(draw) {
const { p1, p2, pA, pB, axis } = temp.Draw;
const xfA = this.m_bodyA.GetTransform();
const xfB = this.m_bodyB.GetTransform();
b2_math_1.b2Transform.MultiplyVec2(xfA, this.m_localAnchorA, pA);
b2_math_1.b2Transform.MultiplyVec2(xfB, this.m_localAnchorB, pB);
b2_math_1.b2Rot.MultiplyVec2(xfA.q, this.m_localXAxisA, axis);
draw.DrawSegment(pA, pB, b2_draw_1.debugColors.joint5);
if (this.m_enableLimit) {
const { lower, upper, perp } = temp.Draw;
b2_math_1.b2Vec2.AddScaled(pA, this.m_lowerTranslation, axis, lower);
b2_math_1.b2Vec2.AddScaled(pA, this.m_upperTranslation, axis, upper);
b2_math_1.b2Rot.MultiplyVec2(xfA.q, this.m_localYAxisA, perp);
draw.DrawSegment(lower, upper, b2_draw_1.debugColors.joint1);
draw.DrawSegment(b2_math_1.b2Vec2.SubtractScaled(lower, 0.5, perp, p1), b2_math_1.b2Vec2.AddScaled(lower, 0.5, perp, p2), b2_draw_1.debugColors.joint2);
draw.DrawSegment(b2_math_1.b2Vec2.SubtractScaled(upper, 0.5, perp, p1), b2_math_1.b2Vec2.AddScaled(upper, 0.5, perp, p2), b2_draw_1.debugColors.joint3);
}
else {
draw.DrawSegment(b2_math_1.b2Vec2.Subtract(pA, axis, p1), b2_math_1.b2Vec2.Add(pA, axis, p2), b2_draw_1.debugColors.joint1);
}
draw.DrawPoint(pA, 5, b2_draw_1.debugColors.joint1);
draw.DrawPoint(pB, 5, b2_draw_1.debugColors.joint4);
}
}
exports.b2WheelJoint = b2WheelJoint;

@@ -6,10 +6,37 @@ import { b2Vec2 } from "../common/b2_math";

import { b2Fixture } from "./b2_fixture";
/**
* Joints and fixtures are destroyed when their associated
* body is destroyed. Implement this listener so that you
* may nullify references to these joints and shapes.
*/
export declare class b2DestructionListener {
/**
* Called when any joint is about to be destroyed due
* to the destruction of one of its attached bodies.
*/
SayGoodbyeJoint(_joint: b2Joint): void;
/**
* Called when any fixture is about to be destroyed due
* to the destruction of its parent body.
*/
SayGoodbyeFixture(_fixture: b2Fixture): void;
}
/**
* Implement this class to provide collision filtering. In other words, you can implement
* this class if you want finer control over contact creation.
*/
export declare class b2ContactFilter {
/**
* Return true if contact calculations should be performed between these two shapes.
*
* @warning for performance reasons this is only called when the AABBs begin to overlap.
*/
ShouldCollide(fixtureA: b2Fixture, fixtureB: b2Fixture): boolean;
static readonly b2_defaultFilter: b2ContactFilter;
}
/**
* Contact impulses for reporting. Impulses are used instead of forces because
* sub-step forces may approach infinity for rigid body collisions. These
* match up one-to-one with the contact points in b2Manifold.
*/
export declare class b2ContactImpulse {

@@ -20,11 +47,69 @@ normalImpulses: number[];

}
/**
* Implement this class to get contact information. You can use these results for
* things like sounds and game logic. You can also get contact results by
* traversing the contact lists after the time step. However, you might miss
* some contacts because continuous physics leads to sub-stepping.
* Additionally you may receive multiple callbacks for the same contact in a
* single time step.
* You should strive to make your callbacks efficient because there may be
* many callbacks per time step.
*
* @warning You cannot create/destroy Box2D entities inside these callbacks.
*/
export declare class b2ContactListener {
/**
* Called when two fixtures begin to touch.
*/
BeginContact(_contact: b2Contact): void;
/**
* Called when two fixtures cease to touch.
*/
EndContact(_contact: b2Contact): void;
/**
* This is called after a contact is updated. This allows you to inspect a
* contact before it goes to the solver. If you are careful, you can modify the
* contact manifold (e.g. disable contact).
* A copy of the old manifold is provided so that you can detect changes.
* Note: this is called only for awake bodies.
* Note: this is called even when the number of contact points is zero.
* Note: this is not called for sensors.
* Note: if you set the number of contact points to zero, you will not
* get an EndContact callback. However, you may get a BeginContact callback
* the next step.
*/
PreSolve(_contact: b2Contact, _oldManifold: b2Manifold): void;
/**
* This lets you inspect a contact after the solver is finished. This is useful
* for inspecting impulses.
* Note: the contact manifold does not include time of impact impulses, which can be
* arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly
* in a separate data structure.
* Note: this is only called for contacts that are touching, solid, and awake.
*/
PostSolve(_contact: b2Contact, _impulse: b2ContactImpulse): void;
static readonly b2_defaultListener: b2ContactListener;
}
/**
* Callback class for AABB queries
* See b2World::Query
*/
export declare type b2QueryCallback = (fixture: b2Fixture) => boolean;
/**
* Callback class for ray casts.
* See b2World::RayCast
* Called for each fixture found in the query. You control how the ray cast
* proceeds by returning a float:
* return -1: ignore this fixture and continue
* return 0: terminate the ray cast
* return fraction: clip the ray to this point
* return 1: don't clip the ray and continue
*
* @param fixture The fixture hit by the ray
* @param point The point of initial intersection
* @param normal The normal vector at the point of intersection
* @returns -1 to filter, 0 to terminate, fraction to clip the ray for
* closest hit, 1 to continue
*/
export declare type b2RayCastCallback = (fixture: b2Fixture, point: b2Vec2, normal: b2Vec2, fraction: number) => number;
//# sourceMappingURL=b2_world_callbacks.d.ts.map

@@ -22,19 +22,30 @@ "use strict";

const b2_common_1 = require("../common/b2_common");
/// Joints and fixtures are destroyed when their associated
/// body is destroyed. Implement this listener so that you
/// may nullify references to these joints and shapes.
/**
* Joints and fixtures are destroyed when their associated
* body is destroyed. Implement this listener so that you
* may nullify references to these joints and shapes.
*/
class b2DestructionListener {
/// Called when any joint is about to be destroyed due
/// to the destruction of one of its attached bodies.
/**
* Called when any joint is about to be destroyed due
* to the destruction of one of its attached bodies.
*/
SayGoodbyeJoint(_joint) { }
/// Called when any fixture is about to be destroyed due
/// to the destruction of its parent body.
/**
* Called when any fixture is about to be destroyed due
* to the destruction of its parent body.
*/
SayGoodbyeFixture(_fixture) { }
}
exports.b2DestructionListener = b2DestructionListener;
/// Implement this class to provide collision filtering. In other words, you can implement
/// this class if you want finer control over contact creation.
/**
* Implement this class to provide collision filtering. In other words, you can implement
* this class if you want finer control over contact creation.
*/
class b2ContactFilter {
/// Return true if contact calculations should be performed between these two shapes.
/// @warning for performance reasons this is only called when the AABBs begin to overlap.
/**
* Return true if contact calculations should be performed between these two shapes.
*
* @warning for performance reasons this is only called when the AABBs begin to overlap.
*/
ShouldCollide(fixtureA, fixtureB) {

@@ -51,5 +62,7 @@ const filterA = fixtureA.GetFilterData();

b2ContactFilter.b2_defaultFilter = new b2ContactFilter();
/// Contact impulses for reporting. Impulses are used instead of forces because
/// sub-step forces may approach infinity for rigid body collisions. These
/// match up one-to-one with the contact points in b2Manifold.
/**
* Contact impulses for reporting. Impulses are used instead of forces because
* sub-step forces may approach infinity for rigid body collisions. These
* match up one-to-one with the contact points in b2Manifold.
*/
class b2ContactImpulse {

@@ -63,33 +76,44 @@ constructor() {

exports.b2ContactImpulse = b2ContactImpulse;
/// Implement this class to get contact information. You can use these results for
/// things like sounds and game logic. You can also get contact results by
/// traversing the contact lists after the time step. However, you might miss
/// some contacts because continuous physics leads to sub-stepping.
/// Additionally you may receive multiple callbacks for the same contact in a
/// single time step.
/// You should strive to make your callbacks efficient because there may be
/// many callbacks per time step.
/// @warning You cannot create/destroy Box2D entities inside these callbacks.
/**
* Implement this class to get contact information. You can use these results for
* things like sounds and game logic. You can also get contact results by
* traversing the contact lists after the time step. However, you might miss
* some contacts because continuous physics leads to sub-stepping.
* Additionally you may receive multiple callbacks for the same contact in a
* single time step.
* You should strive to make your callbacks efficient because there may be
* many callbacks per time step.
*
* @warning You cannot create/destroy Box2D entities inside these callbacks.
*/
class b2ContactListener {
/// Called when two fixtures begin to touch.
/**
* Called when two fixtures begin to touch.
*/
BeginContact(_contact) { }
/// Called when two fixtures cease to touch.
/**
* Called when two fixtures cease to touch.
*/
EndContact(_contact) { }
/// This is called after a contact is updated. This allows you to inspect a
/// contact before it goes to the solver. If you are careful, you can modify the
/// contact manifold (e.g. disable contact).
/// A copy of the old manifold is provided so that you can detect changes.
/// Note: this is called only for awake bodies.
/// Note: this is called even when the number of contact points is zero.
/// Note: this is not called for sensors.
/// Note: if you set the number of contact points to zero, you will not
/// get an EndContact callback. However, you may get a BeginContact callback
/// the next step.
/**
* This is called after a contact is updated. This allows you to inspect a
* contact before it goes to the solver. If you are careful, you can modify the
* contact manifold (e.g. disable contact).
* A copy of the old manifold is provided so that you can detect changes.
* Note: this is called only for awake bodies.
* Note: this is called even when the number of contact points is zero.
* Note: this is not called for sensors.
* Note: if you set the number of contact points to zero, you will not
* get an EndContact callback. However, you may get a BeginContact callback
* the next step.
*/
PreSolve(_contact, _oldManifold) { }
/// This lets you inspect a contact after the solver is finished. This is useful
/// for inspecting impulses.
/// Note: the contact manifold does not include time of impact impulses, which can be
/// arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly
/// in a separate data structure.
/// Note: this is only called for contacts that are touching, solid, and awake.
/**
* This lets you inspect a contact after the solver is finished. This is useful
* for inspecting impulses.
* Note: the contact manifold does not include time of impact impulses, which can be
* arbitrarily large if the sub-step is small. Hence the impulse is provided explicitly
* in a separate data structure.
* Note: this is only called for contacts that are touching, solid, and awake.
*/
PostSolve(_contact, _impulse) { }

@@ -96,0 +120,0 @@ }

@@ -20,33 +20,78 @@ import { b2Vec2, b2Transform, XY } from "../common/b2_math";

import { b2Fixture } from "./b2_fixture";
import { b2Island } from "./b2_island";
import { b2Profile, b2TimeStep, b2StepConfig } from "./b2_time_step";
import { b2ContactFilter, b2ContactListener, b2DestructionListener, b2QueryCallback, b2RayCastCallback } from "./b2_world_callbacks";
/**
* The world class manages all physics entities, dynamic simulation,
* and asynchronous queries. The world also contains efficient memory
* management facilities.
*/
export declare class b2World {
readonly m_contactManager: b2ContactManager;
m_bodyList: b2Body | null;
m_jointList: b2Joint | null;
m_bodyCount: number;
m_jointCount: number;
readonly m_gravity: b2Vec2;
m_allowSleep: boolean;
m_destructionListener: b2DestructionListener | null;
m_inv_dt0: number;
m_newContacts: boolean;
m_locked: boolean;
m_clearForces: boolean;
m_warmStarting: boolean;
m_continuousPhysics: boolean;
m_subStepping: boolean;
m_stepComplete: boolean;
readonly m_profile: b2Profile;
readonly m_island: b2Island;
readonly s_stack: Array<b2Body | null>;
private readonly m_contactManager;
private m_bodyList;
private m_jointList;
private m_bodyCount;
private m_jointCount;
private readonly m_gravity;
private m_allowSleep;
private m_destructionListener;
private m_inv_dt0;
private m_newContacts;
private m_locked;
private m_clearForces;
private m_warmStarting;
private m_continuousPhysics;
private m_subStepping;
private m_stepComplete;
private readonly m_profile;
private readonly m_island;
private readonly s_stack;
private constructor();
/**
* Construct a world object.
*
* @param gravity The world gravity vector.
*/
static Create(gravity: XY): b2World;
/**
* Register a destruction listener. The listener is owned by you and must
* remain in scope.
*/
SetDestructionListener(listener: b2DestructionListener | null): void;
/**
* Get the current destruction listener
*/
GetDestructionListener(): b2DestructionListener | null;
/**
* Register a contact filter to provide specific control over collision.
* Otherwise the default filter is used (b2_defaultFilter). The listener is
* owned by you and must remain in scope.
*/
SetContactFilter(filter: b2ContactFilter): void;
/**
* Register a contact event listener. The listener is owned by you and must
* remain in scope.
*/
SetContactListener(listener: b2ContactListener): void;
/**
* Create a rigid body given a definition. No reference to the definition
* is retained.
*
* @warning This function is locked during callbacks.
*/
CreateBody(def?: b2BodyDef): b2Body;
/**
* Destroy a rigid body given a definition. No reference to the definition
* is retained. This function is locked during callbacks.
*
* @warning This automatically deletes all associated shapes and joints.
* @warning This function is locked during callbacks.
*/
DestroyBody(b: b2Body): void;
private static Joint_Create;
/**
* Create a joint to constrain bodies together. No reference to the definition
* is retained. This may cause the connected bodies to cease colliding.
*
* @warning This function is locked during callbacks.
*/
CreateJoint(def: b2IAreaJointDef): b2AreaJoint;

@@ -63,3 +108,16 @@ CreateJoint(def: b2IDistanceJointDef): b2DistanceJoint;

CreateJoint(def: b2IWheelJointDef): b2WheelJoint;
/**
* Destroy a joint. This may cause the connected bodies to begin colliding.
*
* @warning This function is locked during callbacks.
*/
DestroyJoint(j: b2Joint): void;
/**
* Take a time step. This performs collision detection, integration,
* and constraint solution.
*
* @param timeStep The amount of time to simulate, this should not vary.
* @param velocityIterations For the velocity constraint solver.
* @param positionIterations For the position constraint solver.
*/
private static Step_s_step;

@@ -69,5 +127,29 @@ private static Step_s_stepTimer;

Step(dt: number, iterations: b2StepConfig): void;
/**
* Manually clear the force buffer on all bodies. By default, forces are cleared automatically
* after each call to Step. The default behavior is modified by calling SetAutoClearForces.
* The purpose of this function is to support sub-stepping. Sub-stepping is often used to maintain
* a fixed sized time step under a variable frame-rate.
* When you perform sub-stepping you will disable auto clearing of forces and instead call
* ClearForces after all sub-steps are complete in one pass of your game loop.
*
* @see SetAutoClearForces
*/
ClearForces(): void;
/**
* Query the world for all fixtures that potentially overlap the
* provided AABB.
*
* @param aabb The query box.
* @param callback A user implemented callback class or function.
*/
QueryAABB(aabb: b2AABB, callback: b2QueryCallback): void;
QueryAllAABB(aabb: b2AABB, out?: b2Fixture[]): b2Fixture[];
/**
* Query the world for all fixtures that potentially overlap the
* provided point.
*
* @param point The query point.
* @param callback A user implemented callback class or function.
*/
QueryPointAABB(point: XY, callback: b2QueryCallback): void;

@@ -83,32 +165,122 @@ QueryAllPointAABB(point: XY, out?: b2Fixture[]): b2Fixture[];

private static RayCast_s_point;
/**
* Ray-cast the world for all fixtures in the path of the ray. Your callback
* controls whether you get the closest point, any point, or n-points.
* The ray-cast ignores shapes that contain the starting point.
*
* @param point1 The ray starting point
* @param point2 The ray ending point
* @param callback A user implemented callback class or function.
*/
RayCast(point1: XY, point2: XY, callback: b2RayCastCallback): void;
RayCastOne(point1: XY, point2: XY): b2Fixture | null;
RayCastAll(point1: XY, point2: XY, out?: b2Fixture[]): b2Fixture[];
/**
* Get the world body list. With the returned body, use b2Body::GetNext to get
* the next body in the world list. A NULL body indicates the end of the list.
*
* @returns The head of the world body list.
*/
GetBodyList(): b2Body | null;
/**
* Get the world joint list. With the returned joint, use b2Joint::GetNext to get
* the next joint in the world list. A NULL joint indicates the end of the list.
*
* @returns The head of the world joint list.
*/
GetJointList(): b2Joint | null;
/**
* Get the world contact list. With the returned contact, use b2Contact::GetNext to get
* the next contact in the world list. A NULL contact indicates the end of the list.
*
* @returns The head of the world contact list.
* @warning contacts are created and destroyed in the middle of a time step.
* Use b2ContactListener to avoid missing contacts.
*/
GetContactList(): b2Contact | null;
/**
* Enable/disable sleep.
*/
SetAllowSleeping(flag: boolean): void;
GetAllowSleeping(): boolean;
/**
* Enable/disable warm starting. For testing.
*/
SetWarmStarting(flag: boolean): void;
GetWarmStarting(): boolean;
/**
* Enable/disable continuous physics. For testing.
*/
SetContinuousPhysics(flag: boolean): void;
GetContinuousPhysics(): boolean;
/**
* Enable/disable single stepped continuous physics. For testing.
*/
SetSubStepping(flag: boolean): void;
GetSubStepping(): boolean;
/**
* Get the number of broad-phase proxies.
*/
GetProxyCount(): number;
/**
* Get the number of bodies.
*/
GetBodyCount(): number;
/**
* Get the number of joints.
*/
GetJointCount(): number;
/**
* Get the number of contacts (each may have 0 or more contact points).
*/
GetContactCount(): number;
/**
* Get the height of the dynamic tree.
*/
GetTreeHeight(): number;
/**
* Get the balance of the dynamic tree.
*/
GetTreeBalance(): number;
/**
* Get the quality metric of the dynamic tree. The smaller the better.
* The minimum is 1.
*/
GetTreeQuality(): number;
/**
* Change the global gravity vector.
*/
SetGravity(gravity: XY): void;
/**
* Get the global gravity vector.
*/
GetGravity(): Readonly<b2Vec2>;
/**
* Is the world locked (in the middle of a time step).
*/
IsLocked(): boolean;
/**
* Set flag to control automatic clearing of forces after each time step.
*/
SetAutoClearForces(flag: boolean): void;
/**
* Get the flag that controls automatic clearing of forces after each time step.
*/
GetAutoClearForces(): boolean;
/**
* Shift the world origin. Useful for large worlds.
* The body shift formula is: position -= newOrigin
*
* @param newOrigin The new origin with respect to the old origin
*/
ShiftOrigin(newOrigin: XY): void;
/**
* Get the contact manager for testing.
*/
GetContactManager(): b2ContactManager;
/**
* Get the current profile.
*/
GetProfile(): b2Profile;
Solve(step: b2TimeStep): void;
private Solve;
private static SolveTOI_s_subStep;

@@ -120,4 +292,4 @@ private static SolveTOI_s_backup;

private static SolveTOI_s_toi_output;
SolveTOI(step: b2TimeStep): void;
private SolveTOI;
}
//# sourceMappingURL=b2_world.d.ts.map

@@ -43,7 +43,10 @@ "use strict";

const b2_time_step_1 = require("./b2_time_step");
/// The world class manages all physics entities, dynamic simulation,
/// and asynchronous queries. The world also contains efficient memory
/// management facilities.
/**
* The world class manages all physics entities, dynamic simulation,
* and asynchronous queries. The world also contains efficient memory
* management facilities.
*/
class b2World {
constructor(gravity) {
/** @internal */
this.m_contactManager = new b2_contact_manager_1.b2ContactManager();

@@ -60,2 +63,3 @@ this.m_bodyList = null;

this.m_inv_dt0 = 0;
/** @internal */
this.m_newContacts = false;

@@ -70,30 +74,49 @@ this.m_locked = false;

this.m_profile = new b2_time_step_1.b2Profile();
this.m_island = new b2_island_1.b2Island();
this.m_island = new b2_island_1.b2Island(2 * b2_common_1.b2_maxTOIContacts, b2_common_1.b2_maxTOIContacts, 0, this.m_contactManager.m_contactListener);
this.s_stack = [];
this.m_gravity.Copy(gravity);
}
/// Construct a world object.
/// @param gravity the world gravity vector.
/**
* Construct a world object.
*
* @param gravity The world gravity vector.
*/
static Create(gravity) {
return new b2World(gravity);
}
/// Register a destruction listener. The listener is owned by you and must
/// remain in scope.
/**
* Register a destruction listener. The listener is owned by you and must
* remain in scope.
*/
SetDestructionListener(listener) {
this.m_destructionListener = listener;
}
/// Register a contact filter to provide specific control over collision.
/// Otherwise the default filter is used (b2_defaultFilter). The listener is
/// owned by you and must remain in scope.
/**
* Get the current destruction listener
*/
GetDestructionListener() {
return this.m_destructionListener;
}
/**
* Register a contact filter to provide specific control over collision.
* Otherwise the default filter is used (b2_defaultFilter). The listener is
* owned by you and must remain in scope.
*/
SetContactFilter(filter) {
this.m_contactManager.m_contactFilter = filter;
}
/// Register a contact event listener. The listener is owned by you and must
/// remain in scope.
/**
* Register a contact event listener. The listener is owned by you and must
* remain in scope.
*/
SetContactListener(listener) {
this.m_contactManager.m_contactListener = listener;
this.m_island.m_listener = listener;
}
/// Create a rigid body given a definition. No reference to the definition
/// is retained.
/// @warning This function is locked during callbacks.
/**
* Create a rigid body given a definition. No reference to the definition
* is retained.
*
* @warning This function is locked during callbacks.
*/
CreateBody(def = {}) {

@@ -112,6 +135,9 @@ b2_common_1.b2Assert(!this.IsLocked());

}
/// Destroy a rigid body given a definition. No reference to the definition
/// is retained. This function is locked during callbacks.
/// @warning This automatically deletes all associated shapes and joints.
/// @warning This function is locked during callbacks.
/**
* Destroy a rigid body given a definition. No reference to the definition
* is retained. This function is locked during callbacks.
*
* @warning This automatically deletes all associated shapes and joints.
* @warning This function is locked during callbacks.
*/
DestroyBody(b) {

@@ -203,3 +229,2 @@ var _a, _b;

// Connect to the bodies' doubly linked lists.
// j.m_edgeA.other = j.m_bodyB; // done in b2Joint constructor
j.m_edgeA.prev = null;

@@ -210,3 +235,2 @@ j.m_edgeA.next = j.m_bodyA.m_jointList;

j.m_bodyA.m_jointList = j.m_edgeA;
// j.m_edgeB.other = j.m_bodyA; // done in b2Joint constructor
j.m_edgeB.prev = null;

@@ -234,4 +258,7 @@ j.m_edgeB.next = j.m_bodyB.m_jointList;

}
/// Destroy a joint. This may cause the connected bodies to begin colliding.
/// @warning This function is locked during callbacks.
/**
* Destroy a joint. This may cause the connected bodies to begin colliding.
*
* @warning This function is locked during callbacks.
*/
DestroyJoint(j) {

@@ -266,3 +293,4 @@ b2_common_1.b2Assert(!this.IsLocked());

}
j.m_edgeA.Reset();
j.m_edgeA.prev = null;
j.m_edgeA.next = null;
// Remove from body 2

@@ -278,3 +306,4 @@ if (j.m_edgeB.prev) {

}
j.m_edgeB.Reset();
j.m_edgeB.prev = null;
j.m_edgeB.next = null;
// DEBUG: b2Assert(this.m_jointCount > 0);

@@ -317,7 +346,10 @@ --this.m_jointCount;

// Update contacts. This is where some contacts are destroyed.
const timer = b2World.Step_s_timer.Reset();
this.m_contactManager.Collide();
this.m_profile.collide = timer.GetMilliseconds();
{
const timer = b2World.Step_s_timer.Reset();
this.m_contactManager.Collide();
this.m_profile.collide = timer.GetMilliseconds();
}
// Integrate velocities, solve velocity constraints, and integrate positions.
if (this.m_stepComplete && step.dt > 0) {
const timer = b2World.Step_s_timer.Reset();
this.Solve(step);

@@ -328,2 +360,3 @@ this.m_profile.solve = timer.GetMilliseconds();

if (this.m_continuousPhysics && step.dt > 0) {
const timer = b2World.Step_s_timer.Reset();
this.SolveTOI(step);

@@ -341,11 +374,14 @@ this.m_profile.solveTOI = timer.GetMilliseconds();

}
/// Manually clear the force buffer on all bodies. By default, forces are cleared automatically
/// after each call to Step. The default behavior is modified by calling SetAutoClearForces.
/// The purpose of this function is to support sub-stepping. Sub-stepping is often used to maintain
/// a fixed sized time step under a variable frame-rate.
/// When you perform sub-stepping you will disable auto clearing of forces and instead call
/// ClearForces after all sub-steps are complete in one pass of your game loop.
/// @see SetAutoClearForces
/**
* Manually clear the force buffer on all bodies. By default, forces are cleared automatically
* after each call to Step. The default behavior is modified by calling SetAutoClearForces.
* The purpose of this function is to support sub-stepping. Sub-stepping is often used to maintain
* a fixed sized time step under a variable frame-rate.
* When you perform sub-stepping you will disable auto clearing of forces and instead call
* ClearForces after all sub-steps are complete in one pass of your game loop.
*
* @see SetAutoClearForces
*/
ClearForces() {
for (let body = this.m_bodyList; body; body = body.m_next) {
for (let body = this.m_bodyList; body; body = body.GetNext()) {
body.m_force.SetZero();

@@ -355,6 +391,9 @@ body.m_torque = 0;

}
/// Query the world for all fixtures that potentially overlap the
/// provided AABB.
/// @param aabb the query box.
/// @param callback a user implemented callback class or function.
/**
* Query the world for all fixtures that potentially overlap the
* provided AABB.
*
* @param aabb The query box.
* @param callback A user implemented callback class or function.
*/
QueryAABB(aabb, callback) {

@@ -374,6 +413,9 @@ this.m_contactManager.m_broadPhase.Query(aabb, (proxy) => {

}
/// Query the world for all fixtures that potentially overlap the
/// provided point.
/// @param point the query point.
/// @param callback a user implemented callback class or function.
/**
* Query the world for all fixtures that potentially overlap the
* provided point.
*
* @param point The query point.
* @param callback A user implemented callback class or function.
*/
QueryPointAABB(point, callback) {

@@ -400,3 +442,3 @@ this.m_contactManager.m_broadPhase.QueryPoint(point, (proxy) => {

const { fixture } = fixture_proxy;
const overlap = b2_collision_1.b2TestOverlapShape(shape, index, fixture.GetShape(), fixture_proxy.childIndex, transform, fixture.GetBody().GetTransform());
const overlap = b2_collision_1.b2TestOverlap(shape, index, fixture.GetShape(), fixture_proxy.childIndex, transform, fixture.GetBody().GetTransform());
return !overlap || callback(fixture);

@@ -428,8 +470,11 @@ });

}
/// Ray-cast the world for all fixtures in the path of the ray. Your callback
/// controls whether you get the closest point, any point, or n-points.
/// The ray-cast ignores shapes that contain the starting point.
/// @param point1 the ray starting point
/// @param point2 the ray ending point
/// @param callback a user implemented callback class or function.
/**
* Ray-cast the world for all fixtures in the path of the ray. Your callback
* controls whether you get the closest point, any point, or n-points.
* The ray-cast ignores shapes that contain the starting point.
*
* @param point1 The ray starting point
* @param point2 The ray ending point
* @param callback A user implemented callback class or function.
*/
RayCast(point1, point2, callback) {

@@ -475,23 +520,34 @@ const input = b2World.RayCast_s_input;

}
/// Get the world body list. With the returned body, use b2Body::GetNext to get
/// the next body in the world list. A NULL body indicates the end of the list.
/// @return the head of the world body list.
/**
* Get the world body list. With the returned body, use b2Body::GetNext to get
* the next body in the world list. A NULL body indicates the end of the list.
*
* @returns The head of the world body list.
*/
GetBodyList() {
return this.m_bodyList;
}
/// Get the world joint list. With the returned joint, use b2Joint::GetNext to get
/// the next joint in the world list. A NULL joint indicates the end of the list.
/// @return the head of the world joint list.
/**
* Get the world joint list. With the returned joint, use b2Joint::GetNext to get
* the next joint in the world list. A NULL joint indicates the end of the list.
*
* @returns The head of the world joint list.
*/
GetJointList() {
return this.m_jointList;
}
/// Get the world contact list. With the returned contact, use b2Contact::GetNext to get
/// the next contact in the world list. A NULL contact indicates the end of the list.
/// @return the head of the world contact list.
/// @warning contacts are created and destroyed in the middle of a time step.
/// Use b2ContactListener to avoid missing contacts.
/**
* Get the world contact list. With the returned contact, use b2Contact::GetNext to get
* the next contact in the world list. A NULL contact indicates the end of the list.
*
* @returns The head of the world contact list.
* @warning contacts are created and destroyed in the middle of a time step.
* Use b2ContactListener to avoid missing contacts.
*/
GetContactList() {
return this.m_contactManager.m_contactList;
}
/// Enable/disable sleep.
/**
* Enable/disable sleep.
*/
SetAllowSleeping(flag) {

@@ -511,3 +567,5 @@ if (flag === this.m_allowSleep) {

}
/// Enable/disable warm starting. For testing.
/**
* Enable/disable warm starting. For testing.
*/
SetWarmStarting(flag) {

@@ -519,3 +577,5 @@ this.m_warmStarting = flag;

}
/// Enable/disable continuous physics. For testing.
/**
* Enable/disable continuous physics. For testing.
*/
SetContinuousPhysics(flag) {

@@ -527,3 +587,5 @@ this.m_continuousPhysics = flag;

}
/// Enable/disable single stepped continuous physics. For testing.
/**
* Enable/disable single stepped continuous physics. For testing.
*/
SetSubStepping(flag) {

@@ -535,54 +597,81 @@ this.m_subStepping = flag;

}
/// Get the number of broad-phase proxies.
/**
* Get the number of broad-phase proxies.
*/
GetProxyCount() {
return this.m_contactManager.m_broadPhase.GetProxyCount();
}
/// Get the number of bodies.
/**
* Get the number of bodies.
*/
GetBodyCount() {
return this.m_bodyCount;
}
/// Get the number of joints.
/**
* Get the number of joints.
*/
GetJointCount() {
return this.m_jointCount;
}
/// Get the number of contacts (each may have 0 or more contact points).
/**
* Get the number of contacts (each may have 0 or more contact points).
*/
GetContactCount() {
return this.m_contactManager.m_contactCount;
}
/// Get the height of the dynamic tree.
/**
* Get the height of the dynamic tree.
*/
GetTreeHeight() {
return this.m_contactManager.m_broadPhase.GetTreeHeight();
}
/// Get the balance of the dynamic tree.
/**
* Get the balance of the dynamic tree.
*/
GetTreeBalance() {
return this.m_contactManager.m_broadPhase.GetTreeBalance();
}
/// Get the quality metric of the dynamic tree. The smaller the better.
/// The minimum is 1.
/**
* Get the quality metric of the dynamic tree. The smaller the better.
* The minimum is 1.
*/
GetTreeQuality() {
return this.m_contactManager.m_broadPhase.GetTreeQuality();
}
/// Change the global gravity vector.
/**
* Change the global gravity vector.
*/
SetGravity(gravity) {
this.m_gravity.Copy(gravity);
}
/// Get the global gravity vector.
/**
* Get the global gravity vector.
*/
GetGravity() {
return this.m_gravity;
}
/// Is the world locked (in the middle of a time step).
/**
* Is the world locked (in the middle of a time step).
*/
IsLocked() {
return this.m_locked;
}
/// Set flag to control automatic clearing of forces after each time step.
/**
* Set flag to control automatic clearing of forces after each time step.
*/
SetAutoClearForces(flag) {
this.m_clearForces = flag;
}
/// Get the flag that controls automatic clearing of forces after each time step.
/**
* Get the flag that controls automatic clearing of forces after each time step.
*/
GetAutoClearForces() {
return this.m_clearForces;
}
/// Shift the world origin. Useful for large worlds.
/// The body shift formula is: position -= newOrigin
/// @param newOrigin the new origin with respect to the old origin
/**
* Shift the world origin. Useful for large worlds.
* The body shift formula is: position -= newOrigin
*
* @param newOrigin The new origin with respect to the old origin
*/
ShiftOrigin(newOrigin) {

@@ -600,7 +689,11 @@ b2_common_1.b2Assert(!this.IsLocked());

}
/// Get the contact manager for testing.
/**
* Get the contact manager for testing.
*/
GetContactManager() {
return this.m_contactManager;
}
/// Get the current profile.
/**
* Get the current profile.
*/
GetProfile() {

@@ -615,3 +708,4 @@ return this.m_profile;

const island = this.m_island;
island.Initialize(this.m_bodyCount, this.m_contactManager.m_contactCount, this.m_jointCount, this.m_contactManager.m_contactListener);
island.Resize(this.m_bodyCount);
island.Clear();
// Clear all the island flags.

@@ -745,5 +839,6 @@ for (let b = this.m_bodyList; b; b = b.m_next) {

}
/** @internal */
SolveTOI(step) {
const island = this.m_island;
island.Initialize(2 * b2_common_1.b2_maxTOIContacts, b2_common_1.b2_maxTOIContacts, 0, this.m_contactManager.m_contactListener);
island.Clear();
if (this.m_stepComplete) {

@@ -792,3 +887,3 @@ for (let b = this.m_bodyList; b; b = b.m_next) {

const typeB = bB.m_type;
// DEBUG: b2Assert(typeA !== b2BodyType.b2_staticBody || typeB !== b2BodyType.b2_staticBody);
// DEBUG: b2Assert(typeA === b2BodyType.b2_dynamicBody || typeB === b2BodyType.b2_dynamicBody);
const activeA = bA.IsAwake() && typeA !== b2_body_1.b2BodyType.b2_staticBody;

@@ -892,3 +987,3 @@ const activeB = bB.IsAwake() && typeB !== b2_body_1.b2BodyType.b2_staticBody;

}
if (island.m_contactCount === island.m_contactCapacity) {
if (island.m_contactCount === b2_common_1.b2_maxTOIContacts) {
break;

@@ -982,7 +1077,10 @@ }

exports.b2World = b2World;
/// Take a time step. This performs collision detection, integration,
/// and constraint solution.
/// @param timeStep the amount of time to simulate, this should not vary.
/// @param velocityIterations for the velocity constraint solver.
/// @param positionIterations for the position constraint solver.
/**
* Take a time step. This performs collision detection, integration,
* and constraint solution.
*
* @param timeStep The amount of time to simulate, this should not vary.
* @param velocityIterations For the velocity constraint solver.
* @param positionIterations For the position constraint solver.
*/
b2World.Step_s_step = b2_time_step_1.b2TimeStep.Create();

@@ -989,0 +1087,0 @@ b2World.Step_s_stepTimer = new b2_timer_1.b2Timer();

@@ -36,10 +36,3 @@ /**

export * from "./dynamics/b2_contact_factory";
export * from "./dynamics/b2_contact_solver";
export * from "./dynamics/b2_circle_contact";
export * from "./dynamics/b2_polygon_contact";
export * from "./dynamics/b2_polygon_circle_contact";
export * from "./dynamics/b2_edge_circle_contact";
export * from "./dynamics/b2_edge_polygon_contact";
export * from "./dynamics/b2_chain_circle_contact";
export * from "./dynamics/b2_chain_polygon_contact";
export { b2SetBlockSolve, b2GetBlockSolve } from "./dynamics/b2_contact_solver";
export * from "./dynamics/b2_joint";

@@ -46,0 +39,0 @@ export * from "./dynamics/b2_area_joint";

@@ -30,3 +30,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.b2World = exports.b2BodyType = exports.b2Body = void 0;
exports.b2GetBlockSolve = exports.b2SetBlockSolve = exports.b2World = exports.b2BodyType = exports.b2Body = void 0;
/**

@@ -71,10 +71,5 @@ * \mainpage Box2D API Documentation

__exportStar(require("./dynamics/b2_contact_factory"), exports);
__exportStar(require("./dynamics/b2_contact_solver"), exports);
__exportStar(require("./dynamics/b2_circle_contact"), exports);
__exportStar(require("./dynamics/b2_polygon_contact"), exports);
__exportStar(require("./dynamics/b2_polygon_circle_contact"), exports);
__exportStar(require("./dynamics/b2_edge_circle_contact"), exports);
__exportStar(require("./dynamics/b2_edge_polygon_contact"), exports);
__exportStar(require("./dynamics/b2_chain_circle_contact"), exports);
__exportStar(require("./dynamics/b2_chain_polygon_contact"), exports);
var b2_contact_solver_1 = require("./dynamics/b2_contact_solver");
Object.defineProperty(exports, "b2SetBlockSolve", { enumerable: true, get: function () { return b2_contact_solver_1.b2SetBlockSolve; } });
Object.defineProperty(exports, "b2GetBlockSolve", { enumerable: true, get: function () { return b2_contact_solver_1.b2GetBlockSolve; } });
__exportStar(require("./dynamics/b2_joint"), exports);

@@ -81,0 +76,0 @@ __exportStar(require("./dynamics/b2_area_joint"), exports);

@@ -0,1 +1,2 @@

import { b2Draw } from "../common/b2_draw";
import { b2Vec2, XY } from "../common/b2_math";

@@ -62,3 +63,4 @@ export declare enum b2StretchingModel {

private ApplyBendForces;
Draw(draw: b2Draw): void;
}
//# sourceMappingURL=b2_rope.d.ts.map

@@ -22,2 +22,3 @@ "use strict";

const b2_common_1 = require("../common/b2_common");
const b2_draw_1 = require("../common/b2_draw");
const b2_math_1 = require("../common/b2_math");

@@ -56,3 +57,2 @@ const temp = {

})(b2BendingModel = exports.b2BendingModel || (exports.b2BendingModel = {}));
///
class b2RopeTuning {

@@ -120,3 +120,2 @@ constructor() {

}
///
class b2Rope {

@@ -130,10 +129,9 @@ constructor(def) {

this.m_tuning = new b2RopeTuning();
this.m_count = def.vertices.length;
b2_common_1.b2Assert(def.vertices.length === def.masses.length);
b2_common_1.b2Assert(def.vertices.length >= 3);
this.m_position.Copy(def.position);
this.m_bindPositions = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_ps = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_p0s = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_vs = b2_math_1.b2Vec2.MakeArray(this.m_count);
this.m_count = def.vertices.length;
this.m_bindPositions = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_ps = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_p0s = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_vs = b2_common_1.b2MakeArray(this.m_count, b2_math_1.b2Vec2);
this.m_invMasses = b2_common_1.b2MakeNumberArray(this.m_count);

@@ -198,8 +196,4 @@ for (let i = 0; i < this.m_count; ++i) {

}
Jd1.Copy(e1)
.Skew()
.Scale(-1 / L1sqr);
Jd2.Copy(e2)
.Skew()
.Scale(1 / L2sqr);
b2_math_1.b2Vec2.Skew(e1, Jd1).Scale(-1 / L1sqr);
b2_math_1.b2Vec2.Skew(e2, Jd2).Scale(1 / L2sqr);
b2_math_1.b2Vec2.Negate(Jd1, J1);

@@ -261,3 +255,3 @@ b2_math_1.b2Vec2.Subtract(Jd1, Jd2, J2);

Step(dt, iterations, position) {
if (dt === 0.0) {
if (dt === 0) {
return;

@@ -413,8 +407,4 @@ }

}
Jd1.Copy(d1)
.Skew()
.Scale(-1 / L1sqr);
Jd2.Copy(d2)
.Skew()
.Scale(1 / L2sqr);
b2_math_1.b2Vec2.Skew(d1, Jd1).Scale(-1 / L1sqr);
b2_math_1.b2Vec2.Skew(d2, Jd2).Scale(1 / L2sqr);
b2_math_1.b2Vec2.Negate(Jd1, J1);

@@ -469,8 +459,4 @@ b2_math_1.b2Vec2.Subtract(Jd1, Jd2, J2);

const angle = Math.atan2(a, b);
Jd1.Copy(d1)
.Skew()
.Scale(-1 / L1sqr);
Jd2.Copy(d2)
.Skew()
.Scale(1 / L2sqr);
b2_math_1.b2Vec2.Skew(d1, Jd1).Scale(-1 / L1sqr);
b2_math_1.b2Vec2.Skew(d2, Jd2).Scale(1 / L2sqr);
b2_math_1.b2Vec2.Negate(Jd1, J1);

@@ -607,8 +593,4 @@ b2_math_1.b2Vec2.Subtract(Jd1, Jd2, J2);

const angle = Math.atan2(a, b);
Jd1.Copy(d1)
.Skew()
.Scale(-1 / L1sqr);
Jd2.Copy(d2)
.Skew()
.Scale(1 / L2sqr);
b2_math_1.b2Vec2.Skew(d1, Jd1).Scale(-1 / L1sqr);
b2_math_1.b2Vec2.Skew(d2, Jd2).Scale(1 / L2sqr);
b2_math_1.b2Vec2.Negate(Jd1, J1);

@@ -639,3 +621,12 @@ b2_math_1.b2Vec2.Subtract(Jd1, Jd2, J2);

}
Draw(draw) {
for (let i = 0; i < this.m_count - 1; ++i) {
draw.DrawSegment(this.m_ps[i], this.m_ps[i + 1], b2_draw_1.debugColors.rope);
const pc = this.m_invMasses[i] > 0 ? b2_draw_1.debugColors.ropePointD : b2_draw_1.debugColors.ropePointG;
draw.DrawPoint(this.m_ps[i], 5, pc);
}
const pc = this.m_invMasses[this.m_count - 1] > 0 ? b2_draw_1.debugColors.ropePointD : b2_draw_1.debugColors.ropePointG;
draw.DrawPoint(this.m_ps[this.m_count - 1], 5, pc);
}
}
exports.b2Rope = b2Rope;
{
"name": "@box2d/core",
"version": "0.7.5",
"version": "0.8.0",
"description": "A TypeScript port of Box2D",

@@ -29,3 +29,3 @@ "keywords": [

"scripts": {
"build": "rimraf dist && tsc"
"build": "rimraf dist && tsc && idtsc"
},

@@ -36,2 +36,3 @@ "browserslist": [

"devDependencies": {
"idtsc": "^0.9.0",
"rimraf": "^3.0.2",

@@ -43,3 +44,3 @@ "typescript": "^4.0.2"

},
"gitHead": "f62ed214a9e67fe00eaf6fb23cc6c648db618aee"
"gitHead": "b4aefc12a63ad3684097ab975ad964494a428ad7"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc